Entity Framework-Incluye Múltiples niveles de Propiedades


El método Include() funciona bastante bien para Listas de objetos. ¿Pero qué pasa si tengo que ir dos niveles de profundidad? 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 hacer que esa propiedad se cargue completamente?

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();
}

Poblará solo el Propiedad habilitada (abajo) y no las propiedades de Aplicación o CustomVariableGroup (abajo). ¿Cómo hago que esto suceda?

public class ApplicationWithOverrideVariableGroup : EntityBase
{
    public bool Enabled { get; set; }
    public Application Application { get; set; }
    public CustomVariableGroup CustomVariableGroup { get; set; }
}
Author: Bob Horn, 2012-05-30

7 answers

Para EF 6

using System.Data.Entity;

query.Include(x => x.Collection.Select(y => y.Property))

Ver Observaciones para más ejemplos.

Asegúrese de agregar using System.Data.Entity; para obtener la versión de Include que toma una lambda.


Si está utilizando EF Core, puede usar el nuevo método ThenInclude

query.Include(x => x.Collection)
     .ThenInclude(x => x.Property);
 500
Author: Equiso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-28 20:59:02

Si lo entiendo correctamente, está preguntando sobre la inclusión de propiedades anidadas. En caso afirmativo :

.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)

O

.Include("ApplicationsWithOverrideGroup.NestedProp")  

O

.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")  
 52
Author: Judo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-06 14:47:04

EF Core: Usando "ThenInclude" para cargar múltiples niveles: Por ejemplo:

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
        .ThenInclude(author => author.Photo)
    .ToList();
 32
Author: thangcao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-04 13:48:17

Hice un pequeño ayudante para Entity Framework 6 (estilo.Net Core), para incluir subentidades de una manera agradable.

Ahora está en NuGet : 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.

 19
Author: Lenny32,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-04 14:09:21

También tuve que usar múltiples includes 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:)

 13
Author: dnxit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-17 12:56:57

Más Ejemplos de EFCore en MSDN muestran que se pueden hacer cosas bastante complejas con Include y ThenInclude.

Este es un buen ejemplo de lo complejo que puede llegar (todo esto es 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 'restablece' de nuevo al nivel de la entidad de nivel superior (Instructores).

Incluso puede repetir la misma colección de' primer nivel ' (CourseAssignments) varias veces seguido de comandos ThenIncludes separados para llegar a diferentes entidades.

Tenga en cuenta que su consulta real debe etiquetarse 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 recomendaría encarecidamente que configure el registro y asegúrese de que sus consultas no estén fuera de control si está incluyendo más de una o dos cosas. Es importante ver cómo funciona realmente, y notará que cada 'incluir' por separado suele ser una nueva consulta para evitar que las uniones masivas vuelvan redundantes datos.

AsNoTracking puede acelerar mucho las cosas si no tiene la intención de editar las entidades y volver a guardar.

 7
Author: Simon_Weaver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 08:48:42

Permítanme decir 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 cadenas:

query.Include("Collection.Property")
 0
Author: mrmashal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-29 05:32:36