我有这样的ef类:
class Product
{
public int ProductId {set; get;}
...
public List<ProductBannedIn> BannedIn;
}
public class ProductBannedIn
{
public int ProductId {set; get;}
public Product Product {set; get;}
public int CountryId {set; get;}
public Country Country {set; get;}
}
并希望发出如下请求:
... //query - added some filters before
var products = query.Include(x => x.BannedIn)
.Join(context.ProductTranslation
.Where(x => x.LanguageId == language.LanguageId),
product => product.ProductId,
translation => translation.Product.ProductId,
(x,y) => new {
Id = x. ProductId,
Name = y.Name,
Description = y.Description,
Type = x.TypeId,
BannedIn = x.BannedIn.Select(b => b.CountryId),
}).ToList();
问题:问题是,当我获取例如1000种产品时,这部分
BannedIn = x.BannedIn.Select(b => b.CountryId)
对每一行进行查询,其速度非常慢。 我在调试器中看到的是,对于每种产品,都进行查询以获取BannedIn,但应该已经获取了,因为我有Include
需要实现的目标:
一般来说,应该像对db的1条查询,而不是针对每一行(x.BannedIn)
答案 0 :(得分:5)
这是2.1 EF Core以前版本中具有相关子查询的已知问题(即N + 1查询)。它已在2.1中修复-参见New features in EF Core 2.1-Optimization of correlated subqueries:
我们改进了查询转换,以避免在许多常见情况下执行“ N + 1”个SQL查询,在这种情况下,使用投影中的导航属性会导致将根查询中的数据与相关子查询中的数据连接在一起。优化需要缓冲子查询的结果,我们要求您修改查询以选择采用新行为。
因此,如有可能,请升级到最新的EF Core位,然后按照文档链接中的说明通过向相关子查询中添加.ToList()
来“选择加入”以进行优化:
BannedIn = x.BannedIn.Select(b => b.CountryId).ToList(),
结果将是执行2个SQL查询(这是EF Core与关联的集合一起工作的方式-每个集合1个SQL查询),但不是现在每个产品1个。
答案 1 :(得分:0)
我刚刚更新了ef程序包,并且一切正常