1

同僚のコードに出くわし、おそらく非効率的だと思いました

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);
}

First()私の最初の本能は、linqクエリを保存し、必要に応じて参照することですが、制約のないクエリが行うすべての行を実際に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);
}

私の質問はFirst()、2 番目の linq クエリを呼び出すと、すべての結果が返されなくなるのでしょうか。実際には、元の方法で行う方が速いのでしょうか?

4

1 に答える 1

3

実際には、それがどの LINQ 実装であるかによって異なります。それがLINQ-to-Objects(つまりIEnumerable<T>)の場合、基本的にはデータが何であれ列挙し、最初のアイテムがあればそれを返します。したがってFirst()、次の道徳的同等物です。

foreach(var val in sequence) return val;
throw OopsNoData();

そして、Any()以下とよく比較する必要があります:

foreach(var val in sequence) return true;
return false;

(おそらく、実際の実装では生のイテレータを使用するのではなくforeach)

でも!それが LINQ-to-anything-else である場合、すべての賭けは無効になります。LINQ クエリ (特にIQueryable<T>) は、構成可能になるように設計されています。たとえば、LINQ-to-SQL がFirst()TSQLselect TOP 1 ...クエリになり、他のほとんどのデータベース バックエンドでも同様になると思います。そうです、1行だけが必要であることを伝えると役立つはずです。でも!.Any()私も非常に似たようなことをすることを期待しているので、(理論的には)大きな違いはないはずです。完璧な世界では、TSQL でさえ使用exists(...)されるかもしれませんが、世界は完璧には程遠いです。

調べる方法: SQL トレーサーをアタッチし、最終的な TSQL が何であったかを確認します。


これを行う究極の方法はより簡単です。

var obj = someQuery.FirstOrDefault();
if(obj == null) {
   // no match
} else {
   // do something with "obj"
}
于 2012-07-25T11:14:17.677 に答える