Entity Framework6 包含很多相关实体时,如何提高性能?
How to improve performances in Entity Framework 6 when many related entities are included?
我正在尝试使用 Eager Loding 获取包含许多相关实体的对象列表。最初,我的代码如下所示:
public IEnumerable<EcommerceProduct> GetAllProducts()
{
using (var dbContext = GetDbContext())
{
return (from products in dbContext.EcommerceProducts
select products)
.Include(x => x.ProductLocalizedStrings)
.Include(x => x.Categories)
.Include(x => x.ProductLocalizedPrices)
.Include(x => x.ProductLocalizedStocks).ToList();
}
}
但后来我发现 this article 解释了如何通过 "splitting" 将查询分成更小的查询来提高性能,每个查询最多包含 2 个 Include():
public IEnumerable<EcommerceProduct> GetAllProducts()
{
using (var dbContext = GetDbContext())
{
var productsList = (from products in dbContext.EcommerceProducts
select products)
.Include(x => x.ProductLocalizedStrings)
.Include(x => x.Categories)
.ToList();
productsList = (from products in dbContext.EcommerceProducts
select products)
.Include(x => x.ProductLocalizedPrices)
.Include(x => x.ProductLocalizedStocks)
.ToList();
return productsList;
}
}
现在,这段代码根本不会加快我的查询速度。我基本上取得了相同的结果,但加载时间非常慢。我错过了什么?
EF 使用 Include 生成的 SQL 非常糟糕,但通常服务器会以正确的方式管理它。
您知道在您的情况下性能是与数据库相关还是与具体化过程相关?要测试它,您可以捕获第一个查询(包含所有包含的查询),然后 运行 直接在 DBMS 上捕获它。
查看您的查询,您的上下文可能会变得庞大,这对 EF 不利(即 10,000 个产品,每个产品有 5 个翻译 + 每个产品 5 个价格 + 每个 5 个股票 = 150,000 个上下文条目,这对 EF 不太好)。在这种情况下,您可以尝试使用 AsNoTracking(或者在这部分代码中不使用 EF)。
我们最终切换到延迟加载,将导航属性标记为虚拟并删除所有 "Include()",现在性能好多了。
我正在尝试使用 Eager Loding 获取包含许多相关实体的对象列表。最初,我的代码如下所示:
public IEnumerable<EcommerceProduct> GetAllProducts()
{
using (var dbContext = GetDbContext())
{
return (from products in dbContext.EcommerceProducts
select products)
.Include(x => x.ProductLocalizedStrings)
.Include(x => x.Categories)
.Include(x => x.ProductLocalizedPrices)
.Include(x => x.ProductLocalizedStocks).ToList();
}
}
但后来我发现 this article 解释了如何通过 "splitting" 将查询分成更小的查询来提高性能,每个查询最多包含 2 个 Include():
public IEnumerable<EcommerceProduct> GetAllProducts()
{
using (var dbContext = GetDbContext())
{
var productsList = (from products in dbContext.EcommerceProducts
select products)
.Include(x => x.ProductLocalizedStrings)
.Include(x => x.Categories)
.ToList();
productsList = (from products in dbContext.EcommerceProducts
select products)
.Include(x => x.ProductLocalizedPrices)
.Include(x => x.ProductLocalizedStocks)
.ToList();
return productsList;
}
}
现在,这段代码根本不会加快我的查询速度。我基本上取得了相同的结果,但加载时间非常慢。我错过了什么?
EF 使用 Include 生成的 SQL 非常糟糕,但通常服务器会以正确的方式管理它。
您知道在您的情况下性能是与数据库相关还是与具体化过程相关?要测试它,您可以捕获第一个查询(包含所有包含的查询),然后 运行 直接在 DBMS 上捕获它。
查看您的查询,您的上下文可能会变得庞大,这对 EF 不利(即 10,000 个产品,每个产品有 5 个翻译 + 每个产品 5 个价格 + 每个 5 个股票 = 150,000 个上下文条目,这对 EF 不太好)。在这种情况下,您可以尝试使用 AsNoTracking(或者在这部分代码中不使用 EF)。
我们最终切换到延迟加载,将导航属性标记为虚拟并删除所有 "Include()",现在性能好多了。