[英]Inefficient entity framework queries
我有以下foreach聲明:
foreach (var articleId in cleanArticlesIds)
{
var countArt = context.TrackingInformations.Where(x => x.ArticleId == articleId).Count();
articleDictionary.Add(articleId, countArt);
}
數據庫看起來像這樣
TrackingInformation(Id, ArticleId --some stuff
Article(Id, --some stuff
我想要做的是從TrackingInformations表中獲取所有文章ID計數。 例如:
ArticleId:1 Count:1
ArticleId:2 Count:8
ArticleId:3 Count:5
ArticleId:4 Count:0
所以我可以有一個dictionary<articleId, count>
上下文是實體框架DbContext。 問題在於此解決方案的運行速度非常慢(db中有> 10k的文章,並且它們應該迅速增長)
嘗試下一個查詢以收集分組的數據,它們會添加缺少的信息。 您可以嘗試跳過Select
子句,我不知道EF是否可以很好地處理ToDictionary
。
如果遇到Select n + 1問題(大量數據庫請求),則可以在Select
和ToDictionary
之間添加ToList()
步驟,以便將所有必需的信息帶入內存。
這取決於您所有的映射配置和環境,因此為了獲得良好的性能,您需要對不同的查詢進行一些操作。 主要方法是在很少查詢的情況下在數據庫級別聚合盡可能多的數據。
var articleDictionary =
context.TrackingInformations.Where(trackInfo => cleanArticlesIds.Contains(trackInfo.ArticleId))
.GroupBy(trackInfo => trackInfo.ArticleId)
.Select(grp => new{grp.Key, Count = grp.Count()})
.ToDictionary(info => "ArticleId:" + info.Key,
info => info.Count);
foreach (var missingArticleId in cleanArticlesIds)
{
if(!articleDictionary.ContainsKey(missingArticleId))
articleDictionary.add(missingArticleId, 0);
}
如果TrackingInformation是Article的可導航屬性,則可以執行以下操作:
var result=context.Article.Select(a=>new {a.id,Count=a.TrackingInformation.Count()});
將其放入字典也很簡單:
var result=context.Article
.Select(a=>new {a.id,Count=a.TrackingInformation.Count()})
.ToDictionary(a=>a.id,a=>a.Count);
如果TrackingInforation不是可導航的屬性,則可以執行以下操作:
var result=context.Article.GroupJoin(
context.TrackingInformation,
foo => foo.id,
bar => bar.id,
(x,y) => new { id = x.id, Count = y.Count() })
.ToDictionary(a=>a.id,a=>a.Count);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.