.Include
などを使用して読み込みに関するさまざまな質問がありましたが、SQLフォームのように巨大な結合にクエリすると、情報は、その顧客が1000件を所有し、私はアイテムの情報ではなく、1つの顧客レコードやマルチテーブルセット1000個のアイテムと一緒に複製され、同じ顧客情報の1000行を取得しますEntity Framework - コレクション内のメンバーの特定のナビゲーションプロパティをロードする
context.Customers.Include(c=> c.Inventory).Where(c=>c.ID == id);
//side note, WHY can't I use .Find() after Include?
を行います。これは実際には非効率的で、実際には遅いクエリにつながります。
だから私は、お客様の設定している場合:
//get all customers in TX
var texasCustomers = context.Customers.Where(c=> c.State == "TX");
をそして私はXLSXする輸出でそれらをループにしたい:これは「在庫」テーブルにクエリを生成
foreach (var c in texasCustomers) {
//compile row per item SKU
foreach(var sku in c.Inventory.GroupBy(i=>i.SKU)) {
xlsx.SetCellValue(row, col, c.Name);
//output more customer info here
xlsx.SetCellValue(row, col, sku.Key);
xlsx.SetCellValue(row, col, sku.Sum(i=>i.Quantity));
}
}
PERの顧客。これは高速なクエリですが、SAMEクエリを1000回実行すると、面倒に遅くなります。
だから私はこのようなことをやった:
//get customer key
var customerids = texasCustomers.Select(c=> c.ID).ToArray();
var inventories = context.Inventories.Where(i=> customerids.Contains(i.CustomerID)).ToList();
を...そして今、私の輸出ループはもっとこのようになります...最初の例からNAVプロパティで動作する内部ループは、内となりインベントリオブジェクトの構築済みリストに対して-memory LINQフィルタ:
foreach (var c in texasCustomers) {
//compile row per item SKU
foreach(var sku in inventories.Where(i=> i.CustomerID == c.ID)) {
xlsx.SetCellValue(row, col, c.Name);
//output more customer info and then the sku info
xlsx.SetCellValue(row, col, sku.Key);
xlsx.SetCellValue(row, col, sku.Sum(i=>i.Quantity));
}
}
これが成功した「クエリループごとに」問題回避しますが、明らかな欠点を持っている...そして、ちょうど間違って感じています。
私は何が欠けていますか?一度でコレクションのメンバーのナビゲーションプロパティのすべてを「埋める」ために
texasCustomers.LoadAll(c=> c.Inventories);
:私はのような何かをやらせる秘密のEF機能はどこですか?あるいは私は間違った角度から問題に近づいていますか?
EFが単一の巨大な非正規化テーブルに変換されないSQLを生成するようにクエリを構築する方法はありますか?
ああ、これはもっと良い感じです。これを打つつもりです。ありがとう。 – BLSully
素晴らしい情報!これは私にその道の90%を得ました。私はまだ理解していない(例えば、 '.Find()'から作業していないのですが、処理されていない '.AsQueryable()'を与えると動作しますか?私はEFデータベースのログを4MEGAバイトから7KBにエクスポートしました(4つのバルククエリ対1000x3の断片的なもの) – BLSully
確かに、これは 'IQueryable'でのみ動作します。 'Find'については、ロード関連のデータメソッドのほとんどが直接それと連動しないので、単純な' Where'や 'FirstOrDefault'などを使用してください。単一のエンティティの場合は、 [Find]をクリックし、ナビゲーションコレクションのプロパティの[明示的な読み込み](https://msdn.microsoft.com/en-us/library/jj574232(v=11113).aspx#Anchor_2)を使用します。 Btw、私の答えで使用される手法は、関連するエンティティをリンクから明示的にロードする際に**フィルタを適用するという変形です**セクション。 –