我有两个代码的奇怪问题,我认为应该做同样的事情。任何人都可以解释为什么这段代码需要很长时间才能执行:
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中执行,而第一段代码对每个帐户的每个事务执行多个查询。
答案 0 :(得分:1)
IQueryable
总是使用延迟执行,因为它处理表达式树。当您将DbSet
分配给IEnumerable
时,它会枚举完整集,这意味着您将枚举每个帐户,并在您过滤然后计算时执行相同操作。
第二个代码示例首先过滤集合(您通过扩展IDbSet
的{{1}}属性访问它),因此当您执行计数时,您只对过滤结果执行此操作集。
通过执行以下操作,您可能会再次获得更好的效果:
IQueryable
这将直接在DB中执行计数。
This博客文章很好地解释了事情。