如何以最有效的方式获取懒惰列表的数量?

时间:2013-04-22 10:02:51

标签: c# asp.net-mvc entity-framework entity-framework-4

我在使用EF查询时遇到了一些性能问题。

我们基本上有这个:

public class Article
{
    public int ID { get; set; }
    public virtual List<Visit> Visits { get; set; }
}
public class Visit
{
    public int? ArticleID { get; set; }
    public DateTime Date { get; set; }
}

现在,我想这样做:

Article a = ...;
vm.Count = a.Visits.Count;

问题是,从我可以收集的内容来看,这首先导致整个列表被提取,然后是它的计数。在循环中执行此操作时会产生性能问题。

我认为这是因为对象“太具体”了,所以我试图尽可能地将Visits.Count调用移回存储库(这样我们就可以直接工作了)用DbContext)。这没有用。

有什么建议吗?

3 个答案:

答案 0 :(得分:0)

我认为性能问题可能是延迟加载。 (但需要查看更多代码)。

在从dbcontext检索文章时尝试使用include(a =&gt; a.Visits)。

有关EF效果的更多信息:http://www.asp.net/web-forms/tutorials/continuing-with-ef/maximizing-performance-with-the-entity-framework-in-an-asp-net-web-application

答案 1 :(得分:0)

假设您的数据上下文具有Visits属性:

public class MyDbContext: DbContext
{
    public IDbSet<Article> Articles { get; set; }
    public IDbSet<Visit> Visits { get; set; }
}
你可以这样做:

using (var ctx = new MyDbContext())
{
    var count = ctx.Visits.Where(x => x.ArticleID == 123).Count();
}

此外,如果在处理文章时并不总是需要Visits集合,您可以将其声明为IEnumerable<T>

public class Article
{
    public int ID { get; set; }
    public virtual IEnumerable<Visit> Visits { get; set; }
}

然后依靠延迟加载。

答案 2 :(得分:0)

最后,我采取了另一种方式。

我发现这是以不同方式反复出现的,并且由于域模型的其余部分的设置方式,我做了一些黑客攻击:

在我的VisitRepository中,我创建了一个新函数GetArticleIDsWithVisit(),它通过db.SqlQuery进行直接sql调用,返回一个Dictionary。字典被缓存并用于需要访问计数的所有地方。

不是很漂亮,但我把它包装在存储库中,所以我认为没问题。