6

DataContext を抽象化すると、L2S クエリと L2O クエリは同じになりますか?

私はすでにこれを実証する実用的なプロトタイプを持っていますが、それは非常に単純で、より高度なクエリに耐えられるかどうか疑問に思っています.

誰か知っていますか?

4

3 に答える 3

10

いいえ、それらは同じではありません。

LINQ to Objects クエリはIEnumerable<T>コレクションに対して動作します。クエリはコレクションを反復処理し、コレクション内のアイテムに対して一連のメソッド (たとえば、 など) を実行しますContainsWhere

LINQ to SQL クエリはIQueryable<T>コレクションで動作します。クエリはコンパイラによって式ツリーに変換され、その式ツリーは SQL に変換されてデータベースに渡されます。

メソッドが LINQ to Objects クエリで完全に機能する場合でも、メソッドを SQL に変換できないと LINQ to SQL が文句を言うのはよくあることです。(それ以外の場合は、例外が表示されないことがありますが、LINQ to Objects と LINQ to SQL の間でクエリの結果が微妙に異なる場合があります。)

たとえば、LINQ to SQL はこの単純なクエリで停止しますが、LINQ to Objects は問題ありません。

var query = from n in names
            orderby n.LastName.TrimStart(',', ' ').ToUpper(),
                    n.FirstName.TrimStart(',', ' ').ToUpper()
            select new { n.FirstName, n.LastName };

(多くの場合、これらの制限を回避することは可能ですが、任意の LINQ to Objects クエリが LINQ to SQL クエリとして機能することを保証できないという事実は、それらが同じではないことを示しています!)

于 2009-06-27T10:09:39.320 に答える
6

苛立たしいことに、すべてのIQueryably<T>実装は本質的に漏れやすい抽象化であり、LINQ-to-Objects で機能するものが他のプロバイダーでも機能すると仮定するのは安全ではありません。明らかな関数マッピングとは別に、次のようなものがあります。

  • LINQ-to-SQL はおそらくすべての関数/オーバーロードをサポートできない可能性があります - ここにリストされていますデータ型と関数 (LINQ to SQL)
  • さらに、実際のデータベース サーバーに依存します。Skip/Take などは、SQL Server 2000 と 2005+ では動作が異なり、そのような変換のすべてが SQL Server 2000 で動作するわけではありません
  • EF は、Single または Expression.Invoke (サブ式の呼び出し)、または UDF の使用をサポートしていません
  • Astoria は、Single/First のさまざまな使用法をサポートしています。私が思い出したように、それはサポートしていますが、そうではありWhere(pred).Single()ませんSingle(pred)(これはLINQ-to-SQL の推奨される使用法です

IEnumerable<T>したがって、データベースをシミュレートする単体テストには実際には使用できませんAsQueryable()。それは単に堅牢ではありません。個人的には、この理由からリポジトリ インターフェイスから離れています。Pragmatic LINQ を参照しIQueryable<T>くださいExpression

于 2009-06-27T10:41:54.590 に答える