Entity Framework Core Linq 查询过滤相关实体

Kev*_*ing 5 c# entity-framework-core

我一直在弄清楚如何在使用 Include 时通过 Entity Framework Core 编写关于过滤相关实体的查询,假设我有以下两个类:

public class Order
{
  public int OrderId {get; set;}
  public String CreatedBy{get; set;}
  public virtual Collection<OrderDetail> OrderDetails { get; set; } = new Collection<OrderDetail>();
}

public class OrderDetail
{
   public Int64? OrderDetailID { get; set; }
   public Int64? OrderID { get; set; }
   public string ProductName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如果我想查找由“Jason”创建的所有订单,并且哪个订单详细信息的产品名称等于“Apple”,则在 sql 中它会是:隐藏复制代码

SELECT *
FROM Orders O
INNER JOIN OrderDetail OD ON O.OrderId = OD.OrderId
WHERE O.CreationUser = 'Jason' and OD.ProductName = 'Apple'
Run Code Online (Sandbox Code Playgroud)

但是,我无法弄清楚如何使用 EntityFramework 编写它,如下所示将不起作用:

 await DbContext.Set<Order>()
    .Include(p => p.OrderDetails)
    .Where(o => o.CreationUser == "Jason")
    .Where(o => o.OrderDetails.Where(od => od.ProductName == "Apple"));
Run Code Online (Sandbox Code Playgroud)

有像上面这样的场景,我知道如何使用基本实体类(如上面示例中的 Order)过滤属性,但我不知道如何使用 Include/ThenInclude 处理相关实体,例如在 OrderDetail.ProductName 上进行过滤, 我一直在研究很多但仍然没有任何线索,因此最后我不得不改用 Store procedure,这不是大多数开发人员推荐的。

也许 linq sql 可以做到这一点?

请帮助我更多地了解它!非常感谢所有可以分享您的知识的人!

Sla*_*nov 5

您可以简单地将您的 SQL 脚本转换为 linq:

var orders = (from O in context.Order
              join OD in context.OrderDetail on O.OrderId equals OD.OrderId
              where O.CreatedBy == "Jason" && OD.ProductName == "Apple"
              select order).Distinct().ToList();

//or this solution
orders = context.Set<Order>().Include(p => p.OrderDetails)
   .Where(x => x.CreatedBy == "Jason" && x.OrderDetails.Any(y => y.ProductName == "Apple"))
   .ToList();    
Run Code Online (Sandbox Code Playgroud)