3

我正在使用 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()扩展方法。

尽管这两种方法都达到了相同的结果,但是,一种比另一种更受欢迎吗?(可能在性能上有一些差异?)

4

3 回答 3

9

Enumerable.Count<T>( 的扩展方法) 只是在底层类型是 an时IEnumerable<T>调用,所以 for没有区别。CountICollection<T>List<T>

Queryable.Count<T>( 的扩展方法IQueryable<T>)将使用底层查询提供程序,在许多情况下,它会将计数下推到实际 SQL 中,这将比计算内存中的对象执行得更快。

如果应用了过滤器(例如Count(i => i.Name = "John"))或基础类型不是ICollection<T>,则枚举集合以计算计数。

一个比另一个更受欢迎吗?

我通常更喜欢使用Count(),因为 1)它更便携(底层类型可以是任何实现IEnumerable<T>or的东西IQueryable<T>)和 2)如果需要,以后添加过滤器更容易。

正如蒂姆在他的评论中所说,我也更喜欢使用Any()to,Count() > 0因为它不必实际计算项目 - 它只会检查一个项目的存在。相反,我使用!Any()而不是Count() == 0.

于 2013-08-12T21:19:09.057 回答
2

这取决于底层集合以及 Linq 将从何处提取。例如,如果它是 SQL,那么 using.ToList()将导致查询拉回整个列表,然后对其进行计数。但是,.Count()扩展方法会将其转换为COUNT数据库端的 SQL 语句。在这种情况下,会有明显的性能差异。

对于标准列表或集合,如 D. Stanley 的回答中所述。

于 2013-08-12T21:20:59.813 回答
1

我会说这取决于街区内发生的事情if。如果您只是进行检查以确定是否对底层枚举执行一系列操作,那么在任何情况下都可能不需要它。简单地遍历枚举(ToList也省略)。如果你没有在if块内使用集合,那么你应该避免使用ToList并且绝对使用Any任何Count/Count()方法。

一旦你执行了,ToList那么你将不再使用实体框架,我希望这Count()只会比从那以后稍微慢一点Count,如果基础集合是ICollection<T>它遵循那个实现的话。唯一的开销是确定它是否实现了该接口。

http://msdn.microsoft.com/en-us/library/bb338038.aspx

备注:如果源的类型为implements ICollection<T>,该实现用于获取元素个数。否则,此方法确定计数。

于 2013-08-12T21:44:16.683 回答