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.