Cómo incluir el objeto hijo de un objeto hijo en Entity Framework 5


138

Estoy usando Entity Framework 5 code firsty ASP.NET MVC 3.

Estoy luchando para que el objeto hijo de un objeto hijo se complete. Abajo están mis clases ...

Clase de aplicación;

public class Application
{
     // Partial list of properties

     public virtual ICollection<Child> Children { get; set; }
}

Clase de niño:

public class Child
{
     // Partial list of properties

     public int ChildRelationshipTypeId { get; set; }

     public virtual ChildRelationshipType ChildRelationshipType { get; set; }
}

Clase ChildRelationshipType:

public class ChildRelationshipType
{
     public int Id { get; set; }

     public string Name { get; set; }
}

Parte del método GetAll en el repositorio para devolver todas las aplicaciones:

return DatabaseContext.Applications
     .Include("Children");

La clase Child contiene una referencia a la clase ChildRelationshipType. Para trabajar con los hijos de una aplicación, tendría algo como esto:

foreach (Child child in application.Children)
{
     string childName = child.ChildRelationshipType.Name;
}

Aquí aparece un error de que el contexto del objeto ya está cerrado.

¿Cómo especifico que cada objeto secundario debe incluir el ChildRelationshipTypeobjeto como lo hice anteriormente?


Respuestas:


256

Si incluye la biblioteca System.Data.Entity, puede usar una sobrecarga del Include()método que toma una expresión lambda en lugar de una cadena. A continuación, puede Select()sobre los niños con expresiones Linq en lugar de stringrutas.

return DatabaseContext.Applications
     .Include(a => a.Children.Select(c => c.ChildRelationshipType));

66
Como dijo GraemeMiller, las clases fuertemente tipadas son mejores para la mantenibilidad que el uso de cadenas
Ryan Amies

¿En qué versión estuvo disponible el método lamba? Estoy atascado en una base de código EF 4.0 ... y no puedo hacer que las lamdas funcionen. Gracias por cualquier aportación.
granadaCoder

55
Funcionará en EF 4, solo asegúrese de agregar una referencia aSystem.Data.Entity;
Ryan Amies

55
FYI - En EF 6 el espacio de nombres esMicrosoft.Data.Entity
Brad

Usando EF 5, no pude obtener .Select (x => x.Child) pero esto funcionó - Entities.UserProfile storeProfile = db.UserProfiles .Include (s => s.ShippingAddress) .Include (st => st.ShippingAddress. StateProvince) .Include (b => b.BillingAddress) .Include (bs => bs.BillingAddress.StateProvince) .FirstOrDefault (x => x.UserId == userId);
Geovani Martinez

91

Con EF Core en .NET Core puede usar la palabra clave ThenInclude:

return DatabaseContext.Applications
 .Include(a => a.Children).ThenInclude(c => c.ChildRelationshipType);

Incluya niños de la colección para niños:

return DatabaseContext.Applications
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType1)
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType2);

66
¡¡¡Gracias!!! ¡De mucha ayuda! A veces puedes equivocarte de inteligencia, ¡simplemente ignora eso y construye! :)
muhihsan

Agradable, estaba buscando .net core :)
Andy Clarke

1
¿Y qué pasa si Children es una colección y necesito incluir propiedades debajo de ella?
dodbrian

Encontró una sobrecarga para eso. No era obvio al principio.
dodbrian

1
@dodbrian ¿Cuál fue la sobrecarga? Estoy tratando de anidar. EntoncesIncluir, donde el niño es una colección.
Greg Hardin

22

Terminé haciendo lo siguiente y funciona:

return DatabaseContext.Applications
     .Include("Children.ChildRelationshipType");

76
La forma fuertemente tipada es mejor. Las cuerdas mágicas no son buenas para refactorizar
GraemeMiller

2

Un buen ejemplo del uso del patrón de repositorio genérico y la implementación de una solución genérica para esto podría ser algo como esto.

public IList<TEntity> Get<TParamater>(IList<Expression<Func<TEntity, TParamater>>> includeProperties)

{

    foreach (var include in includeProperties)
     {

        query = query.Include(include);
     }

        return query.ToList();
}

¿Cómo llamaría al método anterior? ¿Podría dar un ejemplo
Jamee

@Jamee -List <Expression <Func <PersonObject, object >>> includers = new List <Expression <Func <PersonObject, object >>> (); includers.Add (x => x.FirstName); Obtener <PersonObject> (incluidos);
gcoleman0828

1
¿Y la consulta proviene de ...?
Doug Beard

Lo siento @DougBeard, no sigo tu pregunta.
gcoleman0828

1
@ gcoleman0828 La variable de consulta en el fragmento de código anterior. ¿Es mágicamente instanciado? ¿De dónde viene?
Doug Beard el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.