如何使用 EF 和 LINQ 更有效地具体化相关项目

How to more efficiently materialize related items using EF and LINQ

新手问...

第 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 };

感谢您的帮助!

如果 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();