【问题标题】:IEnumerable EntityFramework Collection ConfusionIEnumerable EntityFramework 集合混淆
【发布时间】:2014-07-10 12:18:28
【问题描述】:

我认为我认为应该做同样事情的两段代码有点奇怪。谁能解释为什么这段代码需要很长时间才能执行:

IEnumerable<Account> acc_list = null;
acc_list = dbContext.Accounts;
acc_list = acc_list.Where(a => !a.Transactions.Any(t => t.isClosureTransaction));
int count = acc_list.Count();

虽然这段代码是即时的:

IEnumerable<Account> acc_list = null;
acc_list = dbContext.Accounts.Where(a => !a.Transactions.Any(t => t.isClosureTransaction));
int count = acc_list.Count();

在使用 sql profiler 进行一些调查后,第二段代码在一个 sql 中执行,而第一段代码为每个帐户的每个事务执行多个查询。

【问题讨论】:

  • IEnumerable&lt;Account&gt;的使用有关系吗?当您尝试改用 IQueryable&lt;Account&gt; 时会发生什么?
  • 使用 IQueryable 确实可以解决问题。我仍然认为 IEnumerable 不会像这里那样工作,但我想我还得做更多的阅读。

标签: sql .net linq entity-framework


【解决方案1】:

IQueryable 总是使用延迟执行,因为它处理表达式树。当您将 DbSet 分配给 IEnumerable 时,它会枚举完整的集合,这意味着您将枚举每个帐户,并且在您过滤然后计数时也会这样做。

第二个代码示例首先过滤集合(您可以通过扩展 IQueryableIDbSet 属性访问它),因此当您执行计数时,您只对过滤的结果集执行此操作。

通过执行以下操作,您可能会再次获得更好的性能:

dbContext.Accounts.Count(a => !a.Transactions.Any(t => t.isClosureTransaction));

这将直接在数据库中执行计数。

This 博文很好地解释了事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-11
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 2019-07-04
    • 2019-10-22
    相关资源
    最近更新 更多