.net - related - include then include entity framework
EF LINQ incluye entidades mĂșltiples y anidadas (5)
Ok, tengo entidades de tres niveles con la siguiente jerarquía: Curso -> Módulo -> Capítulo
Aquí estaba la declaración original de EF LINQ:
Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters))
.Single(x => x.Id == id);
Ahora, quiero incluir otra entidad llamada Lab asociada a un curso.
¿Cómo incluyo la entidad Lab?
Intenté lo siguiente pero no funcionó:
Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters) && i.Lab)
.Single(x => x.Id == id);
¿Alguna idea sobre incluir la 2da Entidad?
Cualquier consejo o información sería muy apreciado. ¡Gracias!
¿Has intentado simplemente agregar otro Include
?
Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters))
.Include(i => i.Lab)
.Single(x => x.Id == id);
Su solución falla porque Include
no toma un operador booleano
Include(i => i.Modules.Select(s => s.Chapters) && i.Lab)
^^^ ^ ^
list bool operator other list
Actualización Para obtener más información, descargue LinqPad y mire las muestras. Creo que es la forma más rápida de familiarizarse con Linq y Lambda.
Como inicio, la diferencia entre Select
e Include
es que con un Seleccionar usted decide qué desea devolver (también conocido como proyección). La función Incluir es una Carga impaciente , que le dice a Entity Framework que desea que incluya datos de otras tablas.
La sintaxis Include también puede estar en cadena. Me gusta esto:
db.Courses
.Include("Module.Chapter")
.Include("Lab")
.Single(x => x.Id == id);
Pero las muestras en LinqPad explican mejor.
En Entity Framework Core ( EF.core
) puede usar .ThenInclude
para incluir los niveles siguientes.
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ToList();
Más información: https://docs.microsoft.com/en-us/ef/core/querying/related-data
Nota: Digamos que necesita múltiples ThenInclude()
en blog.Posts
, simplemente repita Include(blog => blog.Posts)
y haga otro ThenInclude(post => post.Other)
.
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Other)
.ToList();
También puedes probar
db.Courses.Include("Modules.Chapters").Single(c => c.Id == id);
Uno puede escribir un método de extensión como este:
/// <summary>
/// Includes an array of navigation properties for the specified query
/// </summary>
/// <typeparam name="T">The type of the entity</typeparam>
/// <param name="query">The query to include navigation properties for that</param>
/// <param name="navProperties">The array of navigation properties to include</param>
/// <returns></returns>
public static IQueryable<T> Include<T>(this IQueryable<T> query, params string[] navProperties)
where T : class
{
foreach (var navProperty in navProperties)
query = query.Include(navProperty);
return query;
}
Y úsela así incluso en una implementación genérica:
string[] includedNavigationProperties = new string[] { "NavProp1.SubNavProp", "NavProp2" };
var query = context.Set<T>()
.Include(includedNavigationProperties);
Include
es una parte de la interfaz fluida, por lo que puede escribir varias instrucciones Include
cada una después de otra
db.Courses.Include(i => i.Modules.Select(s => s.Chapters))
.Include(i => i.Lab)
.Single(x => x.Id == id);