如何在 EF Core 中查询多对多关系
Posted
技术标签:
【中文标题】如何在 EF Core 中查询多对多关系【英文标题】:How to query many-to-many releationship in EF Core 【发布时间】:2017-11-13 23:07:24 【问题描述】:我将 .NET Core 和 EF Core 用于 Web 项目。我正在努力如何查询多对多关系。这是我的模型的样子:
public class Begrip
public int ID get; set;
public string Name get; set;
public string Desc get; set;
[Url]
public string URL get; set;
public ICollection<BegripCategory> Categories get; set;
public class Category
public int ID get; set;
public string Name get; set;
public ICollection<BegripCategory> Begrippen get; set;
public class BegripCategory
public int begripId get; set;
public Begrip begrip get; set;
public int categoryId get; set;
public Category category get; set;
还有我的数据库上下文:
public class PBBContext : DbContext
public PBBContext (DbContextOptions<PBBContext> options)
: base(options)
public DbSet<PBB.Models.Movie> Movie get; set;
public DbSet<PBB.Models.Begrip> Begrip get; set;
public DbSet<PBB.Models.Category> Category get; set;
public DbSet<PBB.Models.BegripCategory> BegripCategory get; set;
protected override void OnModelCreating(ModelBuilder modelbuilder)
modelbuilder.Entity<BegripCategory>().HasKey(bc => new bc.begripId, bc.categoryId );
modelbuilder.Entity<BegripCategory>().HasOne(b => b.begrip).WithMany(bg => bg.Categories).HasForeignKey(bc => bc.begripId);
modelbuilder.Entity<BegripCategory>().HasOne(c => c.category).WithMany(ca => ca.Begrippen).HasForeignKey(cc => cc.categoryId);
我试图做的是在 JSON 结果中返回所有“Begrippen”以及所有相应的“类别”,但是,我不知道如何为它们获取“类别”列表。
有什么想法吗?提前致谢。
【问题讨论】:
【参考方案1】:EF Core 不会自动加载相关属性,因此您需要显式执行此操作,但类似以下内容应该可以解决问题:
var result = context.Begrip
.Include(x => x.Categories)
.ThenInclude(x => x.category);
请注意,智能感知目前并不总是在 .ThenInclude
上工作,但即使代码出现红色下划线,它仍应编译。
如果您要将其返回到视图或 API,您可能希望将其映射到 DTO,这样您就不必处理 .Categories[0].category.Name
等。
【讨论】:
它叫Eager loading 在 EF Core 2.1 中使用无法编译的 VS 2017 15.9.7。 事实上,现在我看了你的回答,Begrip
没有Categories
属性,只有BegripCategory
属性。投反对票,请更新答案,我会投赞成票。
另外,很好奇如何在Select()
语句中迭代可变数量的BegripCategory
子实体。那可能吗?如果是这样,你能告诉我怎么做吗?
在这些条件下对我来说仍然编译得很好。 Begrip 确实有一个 Categories 属性,BegripCategory 属性在上下文中,而不是 Begrip 类。【参考方案2】:
如果您需要过滤下面描述的多对多关系,我建议使用 LinQ Enumerable Any 方法,如下所示:
return result.Where(x => x.Categories.Any(c => c.category == categoryId));
返回与特定类别相关的经过过滤的实体列表。
EntityFrameworkCore Relationship query example
【讨论】:
【参考方案3】:扩展@Richard 的回答:
当我执行以下操作时,我在 Visual Studio 2017 15.5.6 中注意到:
return _context.Begrip
.Include(x => x.Categories)
.ThenInclude(y => y.<nothing typed in here yet>)
IntelliSense 起初告诉我 y if 的类型 ICollection 的 BegripCategory 呈现适合集合的方法 什么是令人困惑的,尤其是当我开始时输入“类别”(代替“这里没有输入任何内容”)IntelliSense 会发生变化,就好像我们只处理单个实例而不是 ICollection
只是一个小小的评论,但我希望它有助于节省几分钟的时间混乱。
【讨论】:
以上是关于如何在 EF Core 中查询多对多关系的主要内容,如果未能解决你的问题,请参考以下文章