c# - que - instalar entity framework visual studio 2017
Cargando todas las entidades infantiles con marco de entidades. (3)
Tengo un modelo de datos como este
Me gustaría cargar todas las entidades relacionadas desde una Reconciliación en un objeto de Reconciliación.
Por ahora, la única forma que encontré para cargar todos los entites relacionados en un solo Recon es en múltiples listas. Pero quiero cargar todas las entidades relacionadas en un objeto de Reconciliation
. Si es posible de una manera elegante.
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
También he intentado cargarlo con Include
y Select
pero obtengo esta excepción:
La expresión de ruta de inclusión debe referirse a una propiedad de navegación definida en el tipo. Use rutas de puntos para las propiedades de navegación de referencia y el operador Seleccionar para las propiedades de navegación de la colección.
Y no entiendo cómo podría cargar todos los niños de JrnlEntry utilizando Include
y 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))
Editar
Se las arregló para hacerlo de esta manera también, pero no es muy hermoso:
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))
Hay dos formas de realizar una carga impaciente en Entity Framework:
- Método ObjectQuery.Include
- Carga explícita utilizando el método DbEntityEntry.Collection o el método DbEntityEntry.Reference junto con sus respectivos métodos de carga
También hay maneras de escribir consultas SQL sin procesar en la base de datos:
- El método DbSet.SqlQuery trata con entidades
- El Método Database.SqlQuery trata con tipos arbitrarios
- Método de Database.ExecuteSqlCommand para DDL / DML arbitrario
Para el caso, cuando intenta cargar una base de datos casi completa, sería una buena idea ejecutar un procedimiento de almacenamiento dedicado en su contra.
No estoy seguro de si es demasiado tarde, pero podría beneficiarse de la estructuración de su código como
var acctName = "someName";
var detailList = _repository.Include(e => e.JrnlEntryDetail).Filter(c => c.JrnlEntryDetail.Any(e => e.AcctName == acctName)).Get().ToList();
Pruebe con solo .Include(r => r.ReconciliationDetails)
inicialmente. Luego agregue las declaraciones .Select()
una por una. ¿En qué punto reaparece la excepción? ¡La llamada .SelectMany()
parece un poco sospechosa!
Una segunda pregunta que podría ayudar a identificar el problema ... Después de ejecutar el código que contiene todas las llamadas ToList()
, ¿está completa su entidad de recon
? ¿Es decir, todas sus propiedades de navegación están pobladas? Este debería ser el caso debido al comportamiento automático de "reparación" de Entity Framework.
Con EF, a veces es más eficiente cargar un gráfico de objeto complejo con varias llamadas en lugar de llamadas Include()
encadenadas. Verifique el SQL generado y vea qué es lo más eficiente en su caso.