c# - related - lazy and eager loading in entity framework
Entity Framework-Incluir mĂșltiples niveles de propiedades (7)
El método Include () funciona bastante bien para listas en objetos. ¿Pero qué pasa si necesito profundizar dos niveles? Por ejemplo, el método a continuación devolverá ApplicationServers con las propiedades incluidas que se muestran aquí. Sin embargo, ApplicationsWithOverrideGroup es otro contenedor que contiene otros objetos complejos. ¿Puedo hacer un Include () en esa propiedad también? ¿O cómo puedo conseguir que la propiedad se cargue por completo?
Tal como está ahora, este método:
public IEnumerable<ApplicationServer> GetAll()
{
return this.Database.ApplicationServers
.Include(x => x.ApplicationsWithOverrideGroup)
.Include(x => x.ApplicationWithGroupToForceInstallList)
.Include(x => x.CustomVariableGroups)
.ToList();
}
Rellenará solo la propiedad Enabled (abajo) y no las propiedades Application o CustomVariableGroup (abajo). ¿Cómo puedo hacer que esto suceda?
public class ApplicationWithOverrideVariableGroup : EntityBase
{
public bool Enabled { get; set; }
public Application Application { get; set; }
public CustomVariableGroup CustomVariableGroup { get; set; }
}
Hice un pequeño ayudante para Entity Framework 6 (estilo .Net Core), para incluir las subentidades de una manera agradable.
Está en NuGet ahora: Install-Package ThenInclude.EF6
using System.Data.Entity;
var thenInclude = context.One.Include(x => x.Twoes)
.ThenInclude(x=> x.Threes)
.ThenInclude(x=> x.Fours)
.ThenInclude(x=> x.Fives)
.ThenInclude(x => x.Sixes)
.Include(x=> x.Other)
.ToList();
El paquete está disponible en GitHub .
Más ejemplos de EFCore en MSDN muestran que puedes hacer cosas bastante complejas con Include
y ThenInclude
.
Este es un buen ejemplo de lo complejo que puede obtener (¡esto es todo una declaración!):
viewModel.Instructors = await _context.Instructors
.Include(i => i.OfficeAssignment)
.Include(i => i.CourseAssignments)
.ThenInclude(i => i.Course)
.ThenInclude(i => i.Enrollments)
.ThenInclude(i => i.Student)
.Include(i => i.CourseAssignments)
.ThenInclude(i => i.Course)
.ThenInclude(i => i.Department)
.AsNoTracking()
.OrderBy(i => i.LastName)
.ToListAsync();
Vea cómo puede encadenar Include
incluso después de ThenInclude
y el tipo de "restablecimientos" vuelve al nivel de la entidad de nivel superior (Instructores).
Incluso puede repetir la misma colección de "primer nivel" (CourseAssignments) varias veces seguidas de comandos ThenIncludes
separados para llegar a diferentes entidades secundarias.
Tenga en cuenta que su consulta real debe estar etiquetada al final de la cadena Include
o ThenIncludes
. Lo siguiente NO funciona:
var query = _context.Instructors.AsQueryable();
query.Include(i => i.OfficeAssignment);
var first10Instructors = query.Take(10).ToArray();
Le recomendamos encarecidamente que configure el registro y se asegure de que sus consultas no estén fuera de control si incluye más de una o dos cosas. Es importante ver cómo funciona realmente, y notará que cada "inclusión" es una nueva consulta para evitar que las combinaciones masivas devuelvan datos redundantes.
AsNoTracking
puede acelerar enormemente las cosas si no tiene la intención de editar las entidades y volver a guardarlas.
Permítame decirle claramente que puede usar la sobrecarga de cadenas para incluir niveles anidados independientemente de las multiplicidades de las relaciones correspondientes, si no le importa usar literales de cadena:
query.Include("Collection.Property")
Si te entiendo correctamente, estás preguntando por incluir propiedades anidadas. Si es así :
.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)
o
.Include("ApplicationsWithOverrideGroup.NestedProp")
o
.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")
También tuve que usar múltiples inclusión y en el 3er nivel necesitaba múltiples propiedades
(from e in context.JobCategorySet
where e.Id == id &&
e.AgencyId == agencyId
select e)
.Include(x => x.JobCategorySkillDetails)
.Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.DurationType))
.Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RuleType))
.Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RateType))
.FirstOrDefaultAsync();
Esto puede ayudar a alguien :)
EF Core: uso de "ThenInclude" para cargar varios niveles: por ejemplo:
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.ToList();
Para EF 6
using System.Data.Entity;
query.Include(x => x.Collection.Select(y => y.Property))
Ver Remarks para más ejemplos.
Asegúrese de agregar using System.Data.Entity;
para obtener la versión de Include
que lleva en un lambda.
Para EF Core
Usa el nuevo método ThenInclude
query.Include(x => x.Collection)
.ThenInclude(x => x.Property);