首页 > 解决方案 > 实体框架延迟加载总和子表慢

问题描述

我在实体框架中遇到了 sum 方法的性能问题。为了更好地解释这一点,这是我的表结构:

+----+--------+---------+-------+   +-----------+-----------+-------+
| Id |  Name  | Company | Color |   | ArticleId | Purchaser | Price |
+----+--------+---------+-------+   +-----------+-----------+-------+
|  1 | iPhone | Apple   | Black |   |         1 | Bob       |   350 |
|  2 | iPad   | Apple   | Grey  |   |         1 | Mat       |   220 |
+----+--------+---------+-------+   |         2 | Ivy       |   450 |
                                    +-----------+-----------+-------+

这是 Article 表的相关模型:

public int Id { get; set; }
public string Name { get; set; }
...
[NotMapped]
public decimal? TotalAmount { get; set; }
public virtual ICollection<Purchase> PurchaserList { get; set; }

通过使用延迟加载,实体框架会自动加载所有相关的购买者。然后我简单地将每篇文章的价格相加并将其设置为等于 TotalAmount 属性:

articleList = dbContext.Article.Where(x => x.CompanyId == 10).ToList();

foreach(var article in articleListe)
    article.TotalAmount= article.PurchaserList.Sum(x => x.Price);

但是,对于只有 100 个条目的表,这大约需要 4 秒。当然,这太慢了,我需要加快速度。有没有人有任何建议或任何我可以改进的东西以使这更快?

编辑:

正如 rad 所说,将其从延迟加载更改为急切加载将加载时间从 4 秒提高到 0.17 秒。我删除了虚拟按键并更改了我的代码,如下所示:

articleList = dbContext.Article.Where(x => x.CompanyId == 10).Include(x => x.PurchaserList).ToList();

标签: c#sqlperformanceentity-frameworklinq

解决方案


使用急切加载 ( Include) 而不是延迟加载。
在您的场景中,延迟加载不是一个好的选择,因为对于每个PurchaserList要检索的内容,都会与数据库建立一个新连接(即在您的示例中为 100 个连接),这就是数据库 IO 所花费的时间。
您可以使用 Sql Profiler 跟踪查询和连接。


推荐阅读