Entity Framework Core中如何在同一查询中使用多个DbContext
同一查询中使用多个DbContext的解决方案
首先明确:EF Core本身不支持跨DbContext直接使用Include/ThenInclude做关联查询,因为每个DbContext对应独立的模型映射和数据库会话。不过可以通过以下几种方式实现你的需求:
方法1:手动关联查询(两次查询+内存关联)
先从DbContextTwo获取WebSite及自身关联数据,再从DbContextOne查询对应的App和Client数据,最后在内存中完成关联:
// 从DbContextTwo拉取WebSite及自身关联数据 var webSites = dbContextTwo.GetWorker<WebSite>().DbSet .Include(st => st.Options) .Include(st => st.Cultures) .ThenInclude(clt => clt.Culture) .ToList(); // 提取所有需要关联的AppId var appIds = webSites.Select(st => st.AppId).Distinct().ToList(); // 从DbContextOne获取对应的App和Client数据 var appsWithClients = dbContextOne.App .Include(app => app.Client) .Where(app => appIds.Contains(app.Id)) .ToList(); // 内存中关联WebSite与App foreach (var site in webSites) { site.App = appsWithClients.FirstOrDefault(app => app.Id == site.AppId); }
这种方式适合数据量不大的场景,避免大数据量带来的内存压力。
方法2:在DbContextTwo中添加App模型的映射
如果两个DbContext对应同一个数据库,可以直接在DbContextTwo中添加App和Client的模型映射,并指定对应的数据库模式(如果有):
- 在DbContextTwo中添加DbSet:
public DbSet<App> App { get; set; } public DbSet<Client> Client { get; set; }
- 在DbContextTwo的
OnModelCreating方法中配置模式与关联关系:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 假设App和Client在"dbo"模式下,根据实际情况修改模式名称 modelBuilder.Entity<App>().ToTable("App", "dbo"); modelBuilder.Entity<Client>().ToTable("Client", "dbo"); // 配置WebSite与App的外键关联 modelBuilder.Entity<WebSite>() .HasOne<App>() .WithMany() .HasForeignKey(st => st.AppId); }
- 之后就可以像单个DbContext一样使用Include查询:
dbContextTwo.GetWorker<WebSite>().DbSet .Include(st => st.App) .ThenInclude(app => app.Client) .Include(st => st.Options) .Include(st => st.Cultures) .ThenInclude(clt => clt.Culture) .ToList();
这种方式能直接利用EF的关联查询优化,性能更好,但需要维护两个DbContext中的模型一致性,避免模型变更时遗漏。
方法3:使用数据库视图或存储过程
如果不想修改DbContext的模型映射,可以在数据库中创建包含WebSite、App、Client关联数据的视图,再在DbContextTwo中创建对应视图的模型,直接查询该视图即可。
比如创建视图v_WebSiteWithApp,包含WebSite所有字段及App、Client的相关字段,然后在DbContextTwo中配置:
public DbSet<WebSiteWithApp> WebSiteWithApp { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<WebSiteWithApp>().ToView("v_WebSiteWithApp"); }
之后直接查询WebSiteWithApp就能获取关联好的完整数据。
内容的提问来源于stack exchange,提问作者SteinTech
相关产品推荐
相关产品推荐

