实体框架中的任何V计数

时间:2015-06-03 11:59:16

标签: c# performance linq entity-framework

bool isEmployeeFound;
DbContext DatabaseContext = new DbContext(DatabaseConnectionString);
using (DatabaseContext )
{
    isEmployeeFound= DatabaseContext .Persons.Any(p => p.ExternalId == "123"); -- 1st statement
    isEmployeeFound= DatabaseContext .Persons.Count(p => p.ExternalId == "123") > 0; --2nd statement
}

我的要求是仅检查给定的员工ID;存在于表中或不存在。我不希望表中的行只是一个真或假。我正在使用Entity Framework而不是LINQ to Objects。

我一直在阅读关于任何和伯爵的事情,有些无法决定;我应该使用哪一个?如上所示我的代码应该使用第一个还是第二个语句?

我读到使用Any(它转换为SQL中的Exists)更快,因为一旦它满足条件它停止迭代并返回结果而Count()(它转换为选择SQL中的Count(*))迭代所有然后返回结果。不过这篇文章Which method performs better: .Any() vs .Count() > 0? 说Count()针对Linq对象进行了优化,它的性能优于 任何

我确实进行了一些探索,并尝试使用下面的代码段

获取时间
using (var _dbContext = new DbContext())
{
    string caregiverId = "2301001";
    string clientPhoneNumber = "9795397674";

    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();

    bool iscareGiverFoundWithAny = _dbContext.Persons.Any(p => p.ExternalId == caregiverId);
    bool isClientPhoneNumberFoundWithAny = _dbContext.PhoneNumbers.Any(ph => ph.Number == clientPhoneNumber);

    var testResult1 = stopwatch.Elapsed;
    stopwatch.Restart();

    bool iscareGiverFoundWithCountExt = _dbContext.Persons.Count(p => p.ExternalId == caregiverId) > 0;
    bool isClientPhoneNumberFoundWithCountExt = _dbContext.PhoneNumbers.Count(ph => ph.Number == clientPhoneNumber) > 0;

    var testResult2 = stopwatch.Elapsed;
    stopwatch.Stop();

    Console.WriteLine("Any " + testResult2.TotalSeconds); -- value for this line is coming as 0.0276239
    Console.WriteLine("Count Ext. " + testResult3.TotalSeconds); -- value for this line is coming as 0.0054292
    Console.ReadLine();
}

在运行上面的代码时,它显示Count更快。我很困惑。

请问?

3 个答案:

答案 0 :(得分:5)

简短回答:坚持使用Any()。

您可以安全地忽略您引用的帖子,因为它不是特定于Entity Framework的。在简单集合之上使用LINQ时,是的,可能还有其他注意事项。但是当使用LINQ查询数据库时,您希望避免不必要地迭代额外的数据库记录。

在这种情况下,你说Count()被证明比Any()更快。但是,您所经历的差异是如此微小,至少在数据库性能方面,您可以说在这种情况下您获得了相同的性能。

实际上,如果您的表很小,或者您正在搜索的列被正确编入索引并返回非常少的记录,那么您可以预期性能与Any()和Count()非常相似。

但是,假设你有一个大表,并且你的ExternalId列没有编入索引,那么你将不可避免地注意到Any()大大优于Count()。

重点:最佳案例场景(如果您的数据模型已经过优化),两个选项的表现可能相似。最糟糕的情况是,Any()绝对优于Count()。

除非EF引入了严重的SQL生成错误,否则Count()绝不会超越Any()。所以为了安全起见,我建议你坚持使用Any()。

答案 1 :(得分:0)

在这种情况下

.Any(p => p.ExternalId == "123");
.Count(p => p.ExternalId == "123") > 0;

Any仍然表现更好。

我个人建议您从hibernatingrhinos尝试efprof来获取执行的sql和时间。

答案 2 :(得分:-7)

已经计算了计数,因此访问它的速度更快。

Any()每次调用时都会遍历整个列表。