私はこのようなデータモデルを持っています
Reconciliationのすべての関連エンティティをReconciliationオブジェクトにロードします。
今のところ、関連するすべてのエンティティを単一のReconにロードできる唯一の方法は、複数のリストにあります。 ただし、関連するすべてのエンティティをReconciliation
オブジェクトにロードしたい。可能であれば、エレガントな方法で。
Reconciliation recon = db.Reconciliations
.Where(r => r.ReconNum == 382485).First();
List<ReconciliationDetail> reconDetails = recon.ReconciliationDetails.ToList();
List<JrnlEntryDetail> jrnlDetails = reconDetails.Select(r => r.JrnlEntryDetail).ToList();
List<JrnlEntry> jrnl = jrnlDetails.Select(j => j.JrnlEntry).ToList();
List<ARInvoice> invoices = jrnl.SelectMany(j => j.ARInvoices).ToList();
List<ARInvoiceDetail> invoicesDetail = invoices
.SelectMany(i => i.ARInvoiceDetails).ToList();
List<ARCredMemo> credmemos = jrnl.SelectMany(j => j.ARCredMemoes).ToList();
List<ARCredMemoDetail> credmemosDetail = credmemos
.SelectMany(c => c.ARCredMemoDetails).ToList();
List<IncomingPay> incomingPays = jrnl.SelectMany(j => j.IncomingPays).ToList();
List<IncomingPayDetail> incomingPaysDetail = incomingPays
.SelectMany(i => i.IncomingPayDetails).ToList();
// ... and so on for outgoing pays, AP Invoices AP Cred Memo ...etc
Include
とSelect
でロードしようとしましたが、この例外が発生します:
インクルードパス式は、タイプで定義されたナビゲーションプロパティを参照する必要があります。参照ナビゲーションプロパティには点線のパスを使用し、コレクションナビゲーションプロパティには選択演算子を使用します。
Include
とSelect
を使用してJrnlEntryのすべての子をロードする方法がわかりません。
Reconciliation recon = db.Reconciliations
.Where(r => r.ReconNum == 382485)
.Include(r => r.ReconciliationDetails
.Select(d => d.JrnlEntryDetail)
.Select(jd => jd.JrnlEntry)
.SelectMany(j => j.ARInvoices).SelectMany(i => i.ARInvoiceDetails))
編集
なんとかこの方法でもできましたが、あまり美しくありません:
Reconciliation recon = db.Reconciliations
.Where(r => r.ReconNum == 382485)
.Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail)
.Select(jd => jd.JrnlEntry).Select(j => j.ARInvoices.Select(i => i.ARInvoiceDetails)))
.Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail)
.Select(jd => jd.JrnlEntry).Select(j => j.ARCredMemoes.Select(c => c.ARCredMemoDetails)))
.Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail)
.Select(jd => jd.JrnlEntry).Select(j => j.IncomingPays.Select(i => i.IncomingPayDetails)))
.Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail)
.Select(jd => jd.JrnlEntry).Select(j => j.OutgoingPays.Select(o => o.OutgoingPayDetails)))
.Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail)
.Select(jd => jd.JrnlEntry).Select(j => j.APInvoices.Select(o => o.APInvoiceDetails)))
.Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail)
.Select(jd => jd.JrnlEntry).Select(j => j.APCredMemoes.Select(o => o.APCredMemoDetails)))
.Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail)
.Select(jd => jd.JrnlEntry).Select(j => j.JrnlEntryDetails))
Entity FrameworkでEager Loadingを実行するには2つの方法があります。
データベースに対して Raw SQLクエリ を記述する方法もあります。
この場合、データベースのほぼ全体をロードしようとする場合、専用のストアプロシージャを実行することをお勧めします。
最初は.Include(r => r.ReconciliationDetails)
だけで試してください。次に、.Select()
ステートメントを1つずつ追加します。どの時点で例外が再発しますか? .SelectMany()
呼び出しは少し疑わしいです!
問題の特定に役立つ2番目の質問...すべてのToList()
呼び出しを含むコードを実行した後、recon
エンティティは完全ですか?つまり、すべてのナビゲーションプロパティが設定されていますか?このshouldは、Entity Frameworkの自動「修正」動作のためです。
EFでは、チェーンされたInclude()
呼び出しではなく、複数の呼び出しで複雑なオブジェクトグラフをロードする方が効率的な場合があります。生成されたSQLを確認し、あなたのケースで最も効率的なものを確認してください。
遅れるかどうかはわかりませんが、次のようなコードを構造化することでメリットが得られますか?
var acctName = "someName";
var detailList = _repository.Include(e => e.JrnlEntryDetail).Filter(c => c.JrnlEntryDetail.Any(e => e.AcctName == acctName)).Get().ToList();