通过依赖注入的方式,使用ORM工具Entity Framework查询Mysql数据库中的数据,并实现多表联查
假设我们有一个user用户表,其中occupationid对应的就是下面职业表中的id
职业表Occupations
现在我们需要查出用户的职业是什么,在MySQL中我们可以通过LEFT JOIN实现多表查询。如下sql语句。
SELECT name,opname FROM Users
LEFT JOIN Occupations ON Users.opid = Occupations.id
如果想要在EFCore中完成这种需求应该怎么操作呢。
分别安装如下两个nuget包,具体版本要参考自己实际的MySQL版本
NuGet\Install-Package Microsoft.Extensions.Hosting -Version 8.0.0
NuGet\Install-Package Pomelo.EntityFrameworkCore.MySql -Version 7.0.0
首先创建一个继承自 DbContext
的上下文类,使用DbSet
属性来表示数据库中的表
public class MyContext : DbContext
{
public MyContext(DbContextOptions options)
: base(options)
{
}
public virtual DbSet Users { get; set; } = null!;
public virtual DbSet Occupations { get; set; } = null!;
}
然后分别创建我们数据库两张表的实体类,它们通过导航属性 occupationid 相互关联
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public int occupationid { get; set; }
public Occupation Occupation { get; set; }
}
public class Occupation
{
public int Id { get; set; }
public string opname { get; set; }
}
打开我们的program类,创建一个主机构建器,通过AddDbContextPool注册 MyContext
类型到服务容器中。
然后通过AddHostedService
方法添加一个后台服务,该服务将在应用程序启动时运行,这里我添加的是selectUser服务,也就是项目启动的时候会执行它,接下来我们去写selectUser服务
class Program
{
public static void Main(string[] args)
{
// 创建一个主机构建器,用于配置应用程序的启动和依赖注入。
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
// 配置服务,这里添加了数据库上下文池,用于管理数据库连接。
builder.Services.AddDbContextPool(
p =>
{
p.UseMySql("server=127.0.0.1;uid=root;pwd=password;database=mydb", new MySqlServerVersion("5.7"),
opt => opt.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery));
p.LogTo(Console.WriteLine, LogLevel.Information);
p.EnableSensitiveDataLogging(true);
}, 150);
// 添加宿主服务,我们稍后创建selectUser服务
builder.Services.AddHostedService();
// 构建宿主。
using IHost host = builder.Build();
// 运行宿主,启动应用程序。
host.Run();
}
}
定义一个名为selectUser的类,继承自BackgroundService
,在构造函数中添加参数MyContext ,项目运行时会通过依赖注入给当前类提供一个MyContext上下文,这样,selectUser
类就可以使用这个 DbContext
实例来访问数据库。
使用 _myContext.Users
来访问数据库中的 Users
表。Include(p => p.Occupation)
表示在查询用户时,还要包括关联的 Occupation
实体
public class selectUser : BackgroundService
{
private readonly MyContext _myContext;
public selectUser(MyContext myContext)
{
_myContext = myContext;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var find = _myContext.Users
.Include(p => p.Occupation)
.ToList();
foreach (var user in find)
{
Console.WriteLine(user.Name);
}
return 0;
}
}
这样在程序执行的时候,我们就可以通过多表联查获得用户的职业