如何使用EF和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存在,根据您设置DB上下文的方式,属性将自动获取。不需要联接。第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();

最新更新