LINQの最も難しいまたは最も誤解されている側面は何ですか? [閉まっている]
質問
背景:来月、LINQ
のコンテキストでC#
について、または少なくともSQL
を含む3つの講演を行います。人々が理解するのが難しいと感じるものや、誤った印象を与える可能性のあるものに基づいて、どのトピックにかなりの注意を払う価値があるかを知りたい。式ツリー(および通常はIQueryable
)を使用してクエリをリモートで実行する方法の例を除き、<=>から<=>またはEntity Frameworkについては特に説明しません。
では、<=>について何が難しいと思いますか?誤解については何を見ましたか?例は次のいずれかですが、自分で制限しないでください!
- <=>コンパイラがクエリ式を処理する方法
- ラムダ式
- 式ツリー
- 拡張メソッド
- 匿名型
- <=>
- 遅延実行と即時実行
- ストリーミングとバッファリングされた実行(例:OrderByは遅延されますがバッファリングされます)
- 暗黙的に型指定されたローカル変数
- 複雑な汎用署名の読み取り(例: Enumerable.Join )
解決
遅延実行
他のヒント
遅延実行の概念は今までに打ち負かされるべきだと思いますが、この例は実際にそれを実際に把握するのに役立ちました:
static void Linq_Deferred_Execution_Demo()
{
List<String> items = new List<string> { "Bob", "Alice", "Trent" };
var results = from s in items select s;
Console.WriteLine("Before add:");
foreach (var result in results)
{
Console.WriteLine(result);
}
items.Add("Mallory");
//
// Enumerating the results again will return the new item, even
// though we did not re-assign the Linq expression to it!
//
Console.WriteLine("\nAfter add:");
foreach (var result in results)
{
Console.WriteLine(result);
}
}
上記のコードは次を返します。
Before add:
Bob
Alice
Trent
After add:
Bob
Alice
Trent
Mallory
LINQ
からSQL
までだけではなく、機能は言語に埋め込まれた単なる<=>パーサー以上のものです。
ビッグO表記。 LINQを使用すると、何をしているのかわからない場合、O(n ^ 4)アルゴリズムを気付かずに非常に簡単に記述できます。
Lambda
式は式ツリーと匿名デリゲートの両方に解決できるため、同じ宣言的なlambda
式をIEnumerable<T>
拡張メソッドとIQueryable<T>
拡張メソッドの両方に渡すことができると思います。
方法を長すぎて、Single()
、SingleOrDefault()
などの多くのLINQ拡張メソッドがラムダを使用するオーバーロードを持っていることを理解するには長すぎます。
できること:
Single(x => x.id == id)
これを言う必要はありません-いくつかの悪いチュートリアルで私はそうする習慣になりました
Where(x => x.id == id).Single()
LINQ to SQLでは、DataContext、その使用方法、および使用方法を理解していない人々が常にいます。永続オブジェクトではなく、作業単位オブジェクトであるDataContextが表示されない人が多すぎます。
人々が各操作の新しい時間を作るのではなく、DataContext / session it /などをシングルトン化しようとすることが何度もあります。
そして、IQueryableが評価される前にDataContextを破棄しますが、それはDataContextよりもIQueryableを理解していない人々にとってはより問題です。
他の概念でよく混同されるのは、クエリ構文と式構文です。その時点で最も簡単な方法を使用します。多くの場合、式構文にこだわっています。結局のところ、多くの人は最終的に同じものを生成することに気づいていません。結局クエリはExpressionにコンパイルされます。
LINQの誤解されている部分は、言語拡張であり、データベース拡張または構造ではないことです。
LINQ
はLINQ to SQL
をはるかに超えています。
今ではコレクションで<=>を使用しているので、もう二度と戻りません!
<=>は、2.0のGenericsおよび3.0のAnonymous Type以降、.NETにとって最も重要な機能です。
そしてLambdaができたので、並列プログラミングを待つことができません!
私は、式ツリーとは何か、そしてその理由を知る必要があるかどうかを知りたいと思うでしょう。
私はLINQを初めて使用します。これが最初の試みでつまずいたものです
- 複数のクエリを1つにまとめる
- Visual StudioでのLINQクエリの効果的なデバッグ。
当初気がつかなかったのは、LINQ構文が動作するためにIEnumerable<T>
またはIQueryable<T>
を必要としない ことです。LINQはパターンマッチングに関するものです。
代替テキストhttp://bartdesmet.info/images_wlw/QIsIQueryabletheRightChoiceforMe_13478/image_thumb_3.png
こちら答えです(いいえ、私はそのブログをしませんでした、Bart De Smetは書きました、そして彼は私が見つけたLINQの最高のブロガーの一人です。)
<!> quot; let <!> quot;にまだ問題があります。コマンド(使用したことは一度もありません)およびSelectMany(使用したことがありますが、正しく実行したかどうかはわかりません)
Linqプロバイダー間の抽象化がリークするタイミングを理解する。オブジェクトでは機能するものの、SQLでは機能しないものもあります(例:.TakeWhile)。一部のメソッドはSQL(ToUpper)に変換できますが、他のメソッドは変換できません。一部の手法はオブジェクトでより効率的ですが、他の手法はSQLでより効果的です(異なる結合方法)。
物事のカップル。
- LinqをSQLへのLinqとして考えている人々。
- このパフォーマンスへの影響を考慮することなく、すべてのforeach / logicをLinqクエリに置き換え始めることができると考える人もいます。
OK、需要があるため、Expressionの一部を作成しました。ブロガーとLiveWriterがどのようにフォーマットを組んでいるのか、私は100%には満足していませんが、今のところはそうするでしょう...
とにかく、ここに行きます...特に、人々がより多くの情報を必要としている分野がある場合、私はどんなフィードバックも大好きです。
こちら、好きか嫌いか。 。
エラーメッセージの一部、特にLINQからSQLには、かなり紛らわしいものがあります。 笑顔
私は他の人と同じように、延期された実行に数回噛まれました。私にとって最も混乱しているのは、SQL Serverクエリプロバイダーと、それでできることとできないことです。
まだ空の10進数/お金の列に対してSum()を実行できないという事実には、まだ驚いています。 DefaultIfEmpty()を使用しても機能しません。 :(
LINQで取り上げるべき素晴らしい点は、パフォーマンス面で問題を抱える方法です。たとえば、LINQのカウントをループ条件として使用するのは、本当に賢くありません。
IQueryableは、Expression<Func<T1, T2, T3, ...>>
とFunc<T1, T2, T3, ...>
の両方を受け入れますが、2番目の場合のパフォーマンスの低下についてのヒントは提供しません。
これは、私が何を意味するかを示すコード例です。
[TestMethod]
public void QueryComplexityTest()
{
var users = _dataContext.Users;
Func<User, bool> funcSelector = q => q.UserName.StartsWith("Test");
Expression<Func<User, bool>> expressionSelector = q => q.UserName.StartsWith("Test");
// Returns IEnumerable, and do filtering of data on client-side
IQueryable<User> func = users.Where(funcSelector).AsQueryable();
// Returns IQuerible and do filtering of data on server side
// SELECT ... FROM [dbo].[User] AS [t0] WHERE [t0].[user_name] LIKE @p0
IQueryable<User> exp = users.Where(expressionSelector);
}
誤解とみなされるかどうかはわかりませんが、私にとっては単に不明です。
DataLoadOptionsと、特定のクエリを作成するときにどのテーブルを結合するかを制御する方法について学びました。
詳細については、こちらをご覧ください: MSDN:DataLoadOptions
LINQの最も誤解されている(または理解されていないはずの)側面は、 IQueryable およびカスタムLINQプロバイダーです。
私はしばらくLINQを使用しており、IEnumerableの世界で完全に快適であり、LINQのほとんどの問題を解決できます。
しかし、IQueryable、Expressions、およびカスタムlinqプロバイダーを調べて読み始めたとき、頭を回転させました。かなり複雑なロジックを確認したい場合は、LINQ to SQLの仕組みをご覧ください。
LINQのその側面を理解できることを楽しみにしています...
ほとんどの人が言ったように、最も誤解されている部分は、LINQがT-SQLの単なる代替品であると仮定していると思います。 自分自身をTSQLの第一人者と考える マネージャーは、プロジェクトでLINQを使用することを許可せず、そのようなことをリリースするためにMSを嫌います!!!
クエリの実行時にvarは何を表しますか?
それはiQueryable
、iSingleResult
、iMultipleResult
ですか、または実装に基づいて変更されます。 C#での動的型付けと標準的な静的型付けの使用(と思われるもの)についての推測があります。
ループをネストするのがどれほど簡単かは、誰もが理解しているとは思わない。
例:
from outerloopitem in outerloopitems
from innerloopitem in outerloopitem.childitems
select outerloopitem, innerloopitem
group by
はまだ頭を回転させます。
遅延実行に関する混乱いくつかの簡単なLINQベースのコードをステップ実行し、ウォッチウィンドウで遊んで解決する必要があります。
コンパイルされたクエリ
これらはメソッド呼び出しであるため( still SQL以外の翻訳はできません!)チェーンできず、回避することはほとんど不可能であるという事実は気が遠くなるようなDRYの大きな違反。コンパイルされたクエリを持たないアドホックのためにIQueryable
が必要ですが(重いシナリオのためにコンパイルされたクエリしかありません)、コンパイルされたクエリではそれらを使用できず、代わりに通常のクエリを記述する必要があります再び構文。現在、2つの場所で同じサブクエリを実行しています。何か変更があった場合は、両方を更新することを忘れないでください。悪夢。
LINQ to SQLについての#1誤解は、SQLを有効に活用するためにSQLをまだ知っている必要があるということです。
Linq to Sqlについて誤解されているもう1つの点は、それを機能させるためにデータベースセキュリティを不条理なレベルまで下げる必要があるということです。
3番目のポイントは、Linq to SqlをDynamicクラスと一緒に使用すると(クラス定義が実行時に作成されることを意味する)、膨大な量のジャストインタイムコンパイルが発生することです。これはパフォーマンスを完全に損なう可能性があります。
遅延読み込み。
前述のように、遅延読み込みと遅延実行
LINQ to ObjectsおよびLINQ to XML(IEnumerable)とLINQ to SQL(IQueryable)との違い
HOW すべてのレイヤーにLINQを使用してデータアクセスレイヤー、ビジネスレイヤー、プレゼンテーションレイヤーを構築します。...良い例です。
ほとんどの人が言ったように、最も誤解されている部分は、LINQがT-SQLの単なる代替品であると仮定していると思います。自分をTSQLの第一人者と見なしている私のマネージャーは、プロジェクトでLINQを使用することを許可せず、そのようなものをリリースすることをMSが嫌っています!!!
トランザクション(TransactionScopeを使用しない)