EF Core 多对多关系上的 LINQ 查询

Posted

技术标签:

【中文标题】EF Core 多对多关系上的 LINQ 查询【英文标题】:LINQ Query on EF Core many-to-many relationship 【发布时间】:2021-10-21 02:21:03 【问题描述】:

我在 Entity Framework Core 5 中(按照惯例)建模了以下多对多关系:

  public class Task
  
    public int Id  get; set; 
    public DateTime EndDateTime  get; set; 
    public string Notes  get; set; 

    // Relationships
    public ICollection<TaskOwner> OwnersLink  get; set; 
  

  public class TaskOwner
  
    public int TaskId  get; set; 
    public int OwnerId  get; set; 
    public Status Status  get; set; 

    // Relationships
    public Task Task  get; set; 
    public Owner Owner  get; set; 
  

  public class Owner
  
    public int Id  get; set; 
    public string Name  get; set; 
    public string Email  get; set; 

    // Relationships
    public ICollection<TaskOwner> TasksLink  get; set; 
  

如何使用流畅的 LINQ 语法(例如_dbContext.Owners.Where(s =&gt; s.Id == 1);)构造一个查询,该查询将返回所有没有任何所有者的任务?

【问题讨论】:

我没有看到任何棘手的问题 - 没有所有者的任务自然地用 .Where(task =&gt; !task.OwnersLink.Any()) 表达。 【参考方案1】:

到目前为止给出的两个答案错过或忽略了您拥有此导航属性Task.OwnersLink 的事实。您所要做的就是检查它是否不包含任何物品。

_dbContext.Tasks.Where(t => !t.OwnersLink.Any())

看起来差别很小,但是当查询变大时,在o =&gt; o.TaskId == t.Id等这些不必要的手动“连接”中很容易出错。

【讨论】:

【参考方案2】:

要返回所有没有所有者的任务,试试这个

 var tasks= _dbContext.Tasks
.Where(t => !_dbContext.TaskOwners.Any(to => to.TaskId == t.Id))
.ToList();

【讨论】:

【参考方案3】:
var tasksWithoutOwner = ctx.Tasks
   .Where(x => ctx.TaskOwners.Any(y => y.TaskId == x.Id) == false);

【讨论】:

谢谢@Marc G!

以上是关于EF Core 多对多关系上的 LINQ 查询的主要内容,如果未能解决你的问题,请参考以下文章

EF Core:LINQ 选择“多对多”到“多对多”

如何在 EF Core 中查询多对多关系

改进多对多关系的 LINQ 查询

使用 linq/Entity Framework 查询多对多关系。代码优先

EF Core 多对多关系

定义引用同一个表的多对多关系(EF7/core)