如何使用 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
如何在 EF Core 和 LINQ 中表达 GetDate() 和 DateAdd() 方法?