4

Linqでよく使用する1種類のリクエストがあります。

アイテムのリストにあるID(またはその他のフィールド)を持つデータのセットが必要です。データをロードするために多くの(使用された)インクルードを持っているので、これは重い要求です。

だから例:

私はこの種の構造を持つ人とのテーブルを持っています:

Id; Name; Age; ...

このテーブルは、外部キーにリンクされたいくつかのテーブルであり、これらのデータをロードする必要があります:Car、Company、Address、...

そして今、私は特別な年齢の人々のすべてのデータを取得したいと思います:

List<int> ages = new List<int>(){7,17,27,37,47,57,67,77,87};
using (MyDatabaseEntities context = new MyDatabaseEntities ())
{
   return context.Persons.Include("Car").Include("Company").Include("Address")
                 .Where(p=>ages.Contains(p.Age)).ToList();
}

問題は、Linqが私の「年齢」リストが変更されないことを知らないという印象を持っていることです。次に、すべてのデータ(Car、Company、...)を含む個人の完全なリストをダウンロードして、チェックします。正しい年齢であれば、すべての結果。

それで。

  1. 私は正しいですか?
  2. これを回避する方法は?
4

2 に答える 2

2

次のような投影法を使用できます。

using (MyDatabaseEntities context = new MyDatabaseEntities())
{
   return context.Persons
    .Where(p => ages.Contains(p.Age))
    .Select(p => new {p, p.Car, p.Company, p.Address})
    .ToList();
}
于 2012-04-12T08:59:02.953 に答える
1
  1. 私はあなたが間違っていると思います:あなたがあなたのクエリを「列挙」しない間(あなたの場合は「ToList()」の呼び出しの前に)、あなたは何も「ダウンロード」しません。しかし、SQLで生成されたコードはおそらくそれほどパフォーマンスが良くありません。

コードのデバッグを試みることができます:SQLプロファイラーまたは単に

var yourQuery = context.Persons.Include("Car").Include("Company").Include("Address")
                 .Where(p=>ages.Contains(p.Age));

var HarmQuery = context.Persons
    .Where(p => ages.Contains(p.Age))
    .Select(p => new {p, p.Car, p.Company, p.Address});


return yourQuery.ToList();

「varquery」にブレークポイントを設定し、生成されたSQLを確認し、それをコピーしてdbダイレクトで試して、両方のパフォーマンスを調べます。

編集: 「リンクされた」エンティティのプロパティのサブセットのみが必要な場合、プロジェクションはインクルードよりも確かに優れています:

.Select(p => new{p, p.Car.Name, p.Company.Id, p.Address.Street, p.Address.StreetNumber)

インクルードされたエンティティのすべてのプロパティを取得する「インクルード」では実行できないこと。

于 2012-04-12T09:36:23.400 に答える