[C#]如何使用Linq查询MySQL数据库
Entity Framework Core
Entity Framework Core是微软的开源跨平台的对象关系映射(O/RM)技术,可以通过直接访问内存对象来完成数据库的增删改查等操作,无需编写SQL语句每次从数据库中查询数据了,而且对于C#来说,可以直接用Linq查询表达式对数据库进行查询,可以说是快乐加倍了。
EF Core使用模型执行数据访问,模型是由实体类和表示数据库会话的上下文对象构成,实体类是指数据库中的一个表映射成的一个C#类型,比如下图中右侧是city表的数据库逻辑结构,左侧是该表映射成的C#类,而表中的每一条信息都会映射成一个该类型的对象:
而“表示数据库会话的上下文对象”是指,将要访问的数据库映射为一个DbContext类型的对象,以官方文档中的代码为例:
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
namespace Intro;
public class BloggingContext : DbContext
{
public DbSet Blogs { get; set; }
public DbSet Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public int Rating { get; set; }
public List Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
Blog和Post是两个实体类,分别对应数据库中的两张表的结构,而BloggingContext类是数据库上下文类型(我自己说的),用来映射数据库的结构,该类型中的两个DbSet的集合分别存储两张表的所有信息(所映射成的对象),重写OnConfiguring()方法完成数据库的连接,使用时只需要实例化一个BloggingContext对象即可:
//查询
using (var db = new BloggingContext())
{
var blogs = db.Blogs
.Where(b => b.Rating > 3)
.OrderBy(b => b.Url)
.ToList();
}
//保存数据
using (var db = new BloggingContext())
{
var blog = new Blog { Url = "http://sample.com" };
db.Blogs.Add(blog);
db.SaveChanges();
}
使用EF Core映射MySQL数据库
简单介绍完了EF Core,接下来讲一讲怎么用EF Core映射MySQL数据库,我们以一个简单的.net6控制台程序为例:
1.在项目中添加两个NuGet包:Microsoft.EntityFrameworkCore.Design和Pomelo.EntityFrameworkCore.Mysql
2.安装EF Core命令行工具
dotnet tool install --global dotnet-ef
3.验证安装
dotnet ef
这一步我遇到过一个坑,这个dotnet ef只使用.net默认安装路径C:\Program Files\dotnet下的dotnet.exe,如果.net安在了别的位置它是不识别的,我的解决方案就是直接重新安装了一遍.net,后来我又找了一些资料,找到了另一个可能可行的解决方案:
更改用于启动应用程序的环境变量:
set DOTNET_ROOT=%USERPROFILE%\dotnet
set PATH=%USERPROFILE%\dotnet
也许设置一下这个环境变量就能用了吧,我没试,有兴趣的可以尝试一下。
DbFirst
dotnet ef提供了一条指令可以自动根据已有的数据库生成DbContext类型,并为数据库中的表创建实体类,这种先有数据库后有代码的策略也称之为“数据库优先”,与之相对的有“代码优先”策略,即由程序员写的实体类自动生成数据库的表结构,这里就不赘述了有兴趣可以自行了解一下。scaffold指令的使用方式如下:
dotnet ef dbcontext scaffold <连接字符串> <数据库提供程序> -o <数据库名> -f
其中连接字符串必须包含database=数据库名,举个具体的例子:
dotnet ef dbcontext scaffold "server=localhost;user id=root;password=admin;database=world;" Pomelo.EntityFrameworkCore.MySql -o world -f
在项目文件(.csproj)所在的路径下打开终端,输入上面的指令,运行结果如下:
可以看到根据数据库自动生成了一堆实体类和一个DbContext:
由此就可以在生成的DbContext上对MySQL数据库进行各种操作了。dotnet ef命令行工具的其他参数和指令可以参考官方文档的EF Core 工具参考,上文中的“数据库提供程序”是指由数据库官方或者第三方为EF Core提供的数据库侧的支持,这里我用的是Pomelo.EntityFrameworkCore.MySql,其他数据库的数据库提供程序可以查阅数据库提供程序 - EF Core,值得提醒一下的是,MySQL官方的MySql.EntityFrameworkCore在.net6控制台程序里会抛异常用不了,原因我也不知道,我就换成Pomelo.EntityFrameworkCore.MySql了。