C# .First()是在linq级别还是在返回的可枚举集合上运行?

C# .First()是在linq级别还是在返回的可枚举集合上运行?,c#,.net,linq,C#,.net,Linq,我遇到一个同事的代码,认为它可能效率低下 bool any = (from c in listDeviceMaxDate where c.DeviceKey == m_deviceList[i].deviceKey select c).Any(); if (!any) { latestDate = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue; } else { //

我遇到一个同事的代码,认为它可能效率低下

bool any = (from c in listDeviceMaxDate
             where c.DeviceKey == m_deviceList[i].deviceKey
             select c).Any();

if (!any)
{
    latestDate = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;
}
else
{
    // from the list we have get the lastest max date from the flow table
    DeviceDateTimeItem temp = (from c in listDeviceMaxDate
                                where c.DeviceKey == m_deviceList[i].deviceKey
                                select c).First();

    latestDate = Convert.ToDateTime(temp.dateTimeMax);
}
我的第一反应是存储linq查询,然后根据需要引用它,但后来我意识到
first()
操作符可能会阻止linq实际获取无约束查询所能获得的所有行

我最初是如何考虑重组代码的:

var deviceList = from c in listDeviceMaxDate
                            where c.DeviceKey == m_deviceList[i].deviceKey
                            select c;

if (!deviceList.Any())
{
    latestDate = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;
}
else
{
    // from the list we have get the lastest max date from the flow table
    DeviceDateTimeItem temp = deviceList.First();

    latestDate = Convert.ToDateTime(temp.dateTimeMax);
}

我的问题是,对第二个linq查询的
First()
调用是否会阻止它返回所有结果,因此,按照原来的方式执行是否会更快?

这实际上取决于它是什么linq实现。如果它是LINQ to Objects(即
IEnumerable
),那么它基本上只是枚举数据,不管它是什么,如果是第一项,则返回第一项。因此
First()
在道德上等同于:

foreach(var val in sequence) return val;
throw OopsNoData();
Any()
应与以下各项相比较:

foreach(var val in sequence) return true;
return false;
(它可能在实际实现中使用原始迭代器,而不是
foreach

然而!如果它是林克的任何其他,所有的赌注都是关闭的。LINQ查询(特别是
IQueryable
)被设计为可组合的,我希望LINQ to SQL,例如,将
First()
转换为
select TOP 1…
TSQL查询,类似地,对于大多数其他数据库后端也是如此。所以,是的,告诉它你只想要一行应该是有帮助的。然而!我还希望
.Any()
做一些非常类似的事情,所以(理论上)这不会有很大的区别。在一个完美的世界中,它甚至可以在TSQL中使用
exists(…)
,但这个世界还远远不够完美

找到答案的方法是:附加一个sql跟踪程序,看看最终的TSQL是什么


这样做的最终方法更简单:

var obj = someQuery.FirstOrDefault();
if(obj == null) {
   // no match
} else {
   // do something with "obj"
}

这是Linq到SQL吗
First()
IEnumerable
上操作是Linq
First()
IQueryable
上,从
System.Data.Linq
是Linq到SQL。