3

LINQとSqlDataProviderがWHOLEテーブルを反復処理することに成功したのではないかと思います。

以下の例では、

  • fooアイテム全体が一度だけMEMORYにロードされ、CLRはメモリ内のfooアイテムを繰り返し処理しますか?

  • または、fooアイテムはSQL Serverからチャンクでロードされますか?

  • または、SQL SERVERからMEMORTに一度に1つのfooのみがロードされますか?

  • または ?

 

using (var context = new FooEntities())
{
    var allItems = from foo in context.Foos
                   select foo;      

    // Are all foos LOADED into the MEMORY at once?
    // Or they come from SQL SERVER in chunks?
    foreach (f in foos)
        Console.WriteLine(f.ID);
}
4

3 に答える 3

2

ORM ツールに依存します。不明ですが、EntityFooEntities Frameworkのようですか?

まず、ほとんどの「完全な」ORM は (デフォルトで) ロードするすべてのオブジェクトを ID マネージャー/変更マネージャーにアタッチすることに注意してください。 (ただし、これを無効にする方法もあります)。

次に、多くの場合、次のような結果は.Foos「エンティティ セット」または同様の完全にロードされたデータ セットになることに注意してください。繰り返しますが、必ずしもそうとは限りません。

基本的に、それは問題にない多くの詳細に依存します。ただし、多くの場合、データを非バッファリング (スプーリング) でロードし、change-manager/identity-manager にアタッチせずにロードする API があります。たとえば、LINQ-to-SQL にはObjectTrackingEnabledと他のいくつかのトグルがあります。

データを遅延スプールし、行をオブジェクトに具体化するツールを単に求めている場合は、 dapperが役立つ場合があります。

foreach(EntityType row in connection.Query<EntityType>(
   "select * from TableName", buffered: false))
{
    // fully streaming, no identity manager
    Console.WriteLine(row.Id);
    // ...etc
}
于 2012-10-22T12:56:44.747 に答える
0

はい、アクセスを開始するとすぐに。これらはメモリにロードされます。

オブジェクトのプロパティのみvirtualがロードされません。

すべてのオブジェクトを一度にロードしたくない場合は、ページネーションに使用できTakeますSkip

// Take only 100 objects.
var someitems = allItems.Skip(100).Take(100);

理解を深めるには、記事をご覧ください。

LinqからSQLへの遅延読み込み-遅延読み込み

于 2012-10-22T12:50:17.773 に答える
0

あなたの特定の例では、ほとんどの場合、テーブル全体をメモリに取り込みます。DB への呼び出しは の開始時に行われ、 のforeachようになりますSELECT * FROM FOO。他の人が提案したように、ステップオーバーしてプロファイラーを見てみてください。

SQL Server プロファイラーは、EFProfiler と同様に、この作業に非常に適しています。Linq を使用する場合の「アンチパターン」については、EFProfiler Web サイトのhttp://www.hibernatingrhinos.com/products/efprof/learnを参照してください。ただし、これらは実際にはあらゆる種類のデータアクセスにほとんど当てはまります。Joe Albahari の LINQ クイズ ( http://www.albahari.com/nutshell/linqquiz.aspx ) もチェックして、LINQ で注意すべき興味深い点を確認してください。

于 2012-10-22T13:22:38.870 に答える