我正在使用Entity Framework检索项目列表,如果检索到一些项目,我会使用它们执行某些操作。
var items = db.MyTable.Where(t => t.Expiration < DateTime.Now).ToList();
if(items.Count != 0)
{
// Do something...
}
if
语句也可以写成
if(items.Count() != 0)
{
// Do something...
}
在第一种情况下,.Count
是List<T>.Count
属性。在第二种情况下,.Count()
是IEnumerable<T>.Count()
扩展方法。
虽然两种方法都达到了相同的效果,但是比另一种更优选吗? (可能性能有些不同?)
答案 0 :(得分:8)
Enumerable.Count<T>
,则 IEnumerable<T>
(Count
的扩展方法)只调用ICollection<T>
,因此List<T>
没有区别。
Queryable.Count<T>
(IQueryable<T>
的扩展方法)将使用基础查询提供程序,在许多情况下会将计数推送到实际的SQL,将执行比计算内存中的对象更快。
如果应用过滤器(例如Count(i => i.Name = "John")
)或基础类型不是ICollection<T>
,则枚举该集合以计算计数。
比另一个更优选吗?
我通常更喜欢使用Count()
,因为1)它更具可移植性(底层类型可以是实现IEnumerable<T>
或IQueryable<T>
的任何内容)2)以后更容易添加过滤器如果有必要的话。
正如Tim在评论中指出的那样,我也更喜欢使用Any()
到Count() > 0
,因为它不必实际计算项目 - 它只会检查是否存在一个项目。相反,我使用!Any()
代替Count() == 0
。
答案 1 :(得分:2)
这取决于底层的集合以及Linq将从哪里撤出。例如,如果它是SQL,则使用.ToList()
将导致查询撤回整个列表,然后对其进行计数。但是,.Count()
扩展方法会将其转换为数据库端的SQL COUNT
语句。在这种情况下,会有明显的性能差异。
对于标准列表或集合,它就像D. Stanley的回答中所述。
答案 2 :(得分:1)
我会说这取决于if
区块内发生的事情。如果您只是进行检查以确定是否对基础枚举执行一系列操作,那么在任何情况下都可能不需要它。只需迭代枚举(省略ToList
)。如果您未在if
块中使用该集合,则应避免使用ToList
,并且明确使用Any
覆盖任何Count/Count()
方法。
执行ToList
之后,您就不再使用Entity Framework了,我希望Count()
只比Count
慢一点,因为如果底层集合是{ {1}}它遵循该实施。唯一的开销是确定它是否实现了该接口。
http://msdn.microsoft.com/en-us/library/bb338038.aspx
说明: 如果源的类型实现
ICollection<T>
,则该实现用于获取元素的数量。否则,此方法确定计数。