[英]Inefficient entity framework queries
I have a following foreach statement: 我有以下foreach声明:
foreach (var articleId in cleanArticlesIds)
{
var countArt = context.TrackingInformations.Where(x => x.ArticleId == articleId).Count();
articleDictionary.Add(articleId, countArt);
}
Database looks like this 数据库看起来像这样
TrackingInformation(Id, ArticleId --some stuff
Article(Id, --some stuff
what I want to do is to get all the article ids count from TrackingInformations Table. 我想要做的是从TrackingInformations表中获取所有文章ID计数。 For example:
例如:
ArticleId:1 Count:1
ArticleId:2 Count:8
ArticleId:3 Count:5
ArticleId:4 Count:0
so I can have a dictionary<articleId, count>
所以我可以有一个
dictionary<articleId, count>
Context is the Entity Framework DbContext. 上下文是实体框架DbContext。 The problem is that this solution works very slow (there are > 10k articles in db and they should rapidly grow)
问题在于此解决方案的运行速度非常慢(db中有> 10k的文章,并且它们应该迅速增长)
Try next query to gather grouped data and them add missing information. 尝试下一个查询以收集分组的数据,它们会添加缺少的信息。 You can try to skip
Select
clause, I don't know if EF can handle ToDictionary
in good manner. 您可以尝试跳过
Select
子句,我不知道EF是否可以很好地处理ToDictionary
。
If you encounter Select n + 1 problem (huge amount of database requests), you can add ToList()
step between Select
and ToDictionary
, so that all required information will be brought into memory. 如果遇到Select n + 1问题(大量数据库请求),则可以在
Select
和ToDictionary
之间添加ToList()
步骤,以便将所有必需的信息带入内存。
This depends all your mapping configuration, environment, so in order to get good performance, you need to play a little bit with different queries. 这取决于您所有的映射配置和环境,因此为了获得良好的性能,您需要对不同的查询进行一些操作。 Main approach is to aggregate as much data as possible at database level with few queries.
主要方法是在很少查询的情况下在数据库级别聚合尽可能多的数据。
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);
}
If TrackingInformation is a navigatable property of Article, then you can do this: 如果TrackingInformation是Article的可导航属性,则可以执行以下操作:
var result=context.Article.Select(a=>new {a.id,Count=a.TrackingInformation.Count()});
Putting it into a dictionary is simple as well: 将其放入字典也很简单:
var result=context.Article
.Select(a=>new {a.id,Count=a.TrackingInformation.Count()})
.ToDictionary(a=>a.id,a=>a.Count);
If TrackingInforation isn't a navigatable property, then you can do: 如果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.