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()",现在性能好多了。