Подтвердить что ты не робот

Загрузка всех дочерних объектов с инфраструктурой сущностей

У меня есть модель данных, подобная этой

Data Model

Я хотел бы загрузить все связанные объекты из объекта "Согласование в объект примирения".

Теперь единственный способ найти все связанные с ним права на один 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 path должно быть указано свойство навигации, определенное в типе. Используйте пунктирные пути для ссылочных навигационных свойств и оператор Select для свойств навигации для коллекции.

И я не понимаю, как я мог загружать все дочерние элементы JrnlEntry с помощью Include и Select

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))

Edit

Удалось это сделать тоже, но это не очень красиво:

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))
4b9b3361

Ответ 1

Есть два способа выполнить Ожидание загрузки в Entity Framework:

Есть также манеры писать Необработанные SQL-запросы для базы данных:

В случае, когда вы пытаетесь загрузить почти всю базу данных, было бы неплохо выполнить над ним специальную процедуру хранения.

Ответ 2

Сначала попробуйте только .Include(r => r.ReconciliationDetails). Затем добавьте операторы .Select() один за другим. В какой момент снова появляется исключение? Вызов .SelectMany() выглядит немного подозрительным для меня!

Второй вопрос, который может помочь выявить проблему... После запуска кода, который содержит все вызовы ToList(), завершен ли ваш объект recon? т.е. все его навигационные свойства заполнены? Это должно происходить из-за автоматического "исправления" поведения Entity Framework.

С EF, иногда более эффективно загружать граф сложного объекта несколькими вызовами, а не цепочками Include() вызовов. Проверьте сгенерированный SQL и посмотрите, что наиболее эффективно в вашем случае.

Ответ 3

Не уверен, что это возможно, но вы могли бы использовать структурирование своего кода, например

var acctName = "someName";

var detailList =  _repository.Include(e => e.JrnlEntryDetail).Filter(c => c.JrnlEntryDetail.Any(e => e.AcctName == acctName)).Get().ToList();