如何使用 EF 和 LINQ 更有效地实现相关项目

Posted

技术标签:

【中文标题】如何使用 EF 和 LINQ 更有效地实现相关项目【英文标题】:How to more efficiently materialize related items using EF and LINQ 【发布时间】:2022-01-08 12:54:24 【问题描述】:

一个新手问...

第 1 部分

假设我有 3 个类(以及它们等效的 SQL 表):

Product 

     int Id;
     List<Keyword> Keywords;
     List<Serial> Serials;

Keyword

  int Id;
  int ProductId; // FK to Product
  string Name;

Serial

   int Id;
   int ProductId; // FK to Product
   string SerialNumber;

加载PRODUCT == 123时,我们可以这样做:

   item = db.Products.FirstOrDefault(p => p.Id == 123);
   item.Keywords  = db.Keywords.Where(p => p.ProductId == 123).ToList();
   item.Serials   = db.Serials.Where(p => p.ProductId == 123).ToList();

这是 3 个 SQL 语句。

或者我们可以这样做:

    from product in db.Products.AsNoTracking()
        join link1 in Db.Keywords.AsNoTracking()
        on product.Id equals link1.ProductId into kwJoin
    from keyword  in kwJoin.DefaultIfEmpty() 
        join link2 in Db.Serials.AsNoTracking()
        on product.Id equals link2.ProductId into serJoin
    from serial   in serJoin.DefaultIfEmpty() 
        where product.Id == 123
    select new  product, keyword, serial ;

它给出了 1 个 SQL 语句,但产生了太多需要合并在一起的行(关键字数 x 序列数)

两者似乎都没有效率。有没有更好的办法?

第 2 部分

作为另一个问题,但使用相同的示例,当我们有这样的连接时:

    from product in db.Products.AsNoTracking()
        join link1 in Db.Keywords.AsNoTracking()
        on product.Id equals link1.ProductId into kwJoin
    from keyword  in kwJoin.DefaultIfEmpty() 
    select new  product, keyword ;

有没有办法直接在产品中的select语句中分配关键字?

    select new  product, product.Keywords = keyword ;

感谢您的帮助!

【问题讨论】:

【参考方案1】:

如果 FK 存在,则根据您设置数据库上下文的方式,将自动获取属性。无需连接。第 1 部分查询很简单,因为它有一个过滤器。第 2 部分可能存在问题,具体取决于需要从数据库中获取多少记录。在列表中的每个产品都有关键字对象之后,您可以将字段映射到匿名对象(或 DTO)。

第 1 部分

item = db.Products
          .Include(p=>p.Keywords)
          .Include(s=>s.Serials)
          .Where(p => p.Id == 123)
          .FirstOrDefault();

第 2 部分

products = db.Products.Include(p=>p.Keywords).ToList();

【讨论】:

谢谢。那行得通。现在我是半新手......

以上是关于如何使用 EF 和 LINQ 更有效地实现相关项目的主要内容,如果未能解决你的问题,请参考以下文章

在不使用 LINQ 和 EF 的情况下从 ASP.NET 切换到 ASP MVC

如何使用 LINQ 和 EF 将记录复制到另一个表及其关系

如何在 EF Core 和 LINQ 中表达 GetDate() 和 DateAdd() 方法?

linq和EF查询的用法和区分

如何使用 LINQ 针对 Azure Cosmos Document DB SQL API 有效地进行动态查询?

使用 EF6 优化 LINQ 查询