entity framework 4.1 - studio - Marco de la entidad: ¿hay alguna manera de cargar automáticamente las entidades secundarias sin Include()?
descargar entity framework para visual studio 2017 (2)
No, no puedes hacer eso en el mapeo . La solución típica es el método de extensión simple:
public static IQueryable<Car> BuildCar(this IQueryable<Car> query) {
return query.Include(x => x.Wheels)
.Include(x => x.Doors)
.Include(x => x.Engine)
.Include(x => x.Bumper)
.Include(x => x.Windows);
}
Ahora, cada vez que quiera consultar el Car
con todas las relaciones, lo hará:
var query = from car in db.Cars.BuildCar()
where car.Make == "Ford"
select car;
Editar:
No puede anidar llamadas de esa manera. Incluya trabajos en la entidad central con la que está trabajando: esa entidad define la forma de la consulta, por lo que después de llamar a Include(x => Wheels)
todavía está trabajando con IQueryable<Car>
y no puede llamar al método de extensión para IQueryable<Engine>
. Debe comenzar de nuevo con el Car
:
public static IQueryable<Car> BuildCarWheels(this IQuerable<Car> query) {
// This also answers how to eager load nested collections
// Btw. only Select is supported - you cannot use Where, OrderBy or anything else
return query.Include(x => x.Wheels.Select(y => y.Rim))
.Include(x => x.Wheels.Select(y => y.Tire));
}
y usarás ese método de esta manera:
public static IQueryable<Car> BuildCar(this IQueryable<Car> query) {
return query.BuildCarWheels()
.Include(x => x.Doors)
.Include(x => x.Engine)
.Include(x => x.Bumper)
.Include(x => x.Windows);
}
El uso no Include(x => x.Wheels)
porque debe agregarse automáticamente cuando solicite la carga ansiosa de sus entidades anidadas.
Tenga cuidado con las consultas complejas producidas por estructuras de carga tan complejas e impacientes. Puede dar como resultado un rendimiento muy bajo y una gran cantidad de datos duplicados transferidos desde la base de datos.
¿Hay alguna forma de decorar tus clases de POCO para cargar automáticamente las entidades secundarias sin tener que usar Include()
cada vez que las cargas?
Digamos que tengo un coche de clase, con propiedades de tipo complejo para ruedas, puertas, motor, paragolpes, ventanas, escapes, etc. Y en mi aplicación necesito cargar mi auto desde mi DbContext en 20 lugares diferentes con diferentes consultas, etc. No quiero tener que especificar que quiero incluir todas las propiedades cada vez que quiero cargar mi auto.
quiero decir
List<Car> cars = db.Car
.Where(x => c.Make == "Ford").ToList();
//NOT .Include(x => x.Wheels).Include(x => x.Doors).Include(x => x.Engine).Include(x => x.Bumper).Include(x => x.Windows)
foreach(Car car in cars)
{
//I don''t want a null reference here.
String myString = car.**Bumper**.Title;
}
¿Puedo de alguna manera decorar mi clase POCO o en mi OnModelCreating()
o establecer una configuración en EF que diga que solo cargue todas las partes de mi auto cuando cargue mi auto? Quiero hacerlo con entusiasmo, por lo que entiendo que está haciendo que mis propiedades de navegación sean virtuales. Sé que NHibernate admite una funcionalidad similar.
Me pregunto si me estoy perdiendo algo. ¡Gracias por adelantado!
Aclamaciones,
Nathan
Me gusta la solución a continuación, pero me pregunto si puedo anidar las llamadas a los métodos de extensión. Por ejemplo, supongamos que tengo una situación similar con Engine, donde tiene muchas partes que no quiero incluir en todas partes. ¿Puedo hacer algo como esto? (No he encontrado una forma de que esto funcione todavía). De esta forma, si más tarde descubro que Engine necesita FuelInjectors, puedo agregarlo solo en BuildEngine y no tener que agregarlo también en BuildCar. Además, si puedo anidar las llamadas, ¿cómo puedo anidar una llamada a una colección? Me gusta llamar a BuildWheel () para cada una de mis ruedas desde mi BuildCar ()?
public static IQueryable<Car> BuildCar(this IQueryable<Car> query) {
return query.Include(x => x.Wheels).BuildWheel()
.Include(x => x.Doors)
.Include(x => x.Engine).BuildEngine()
.Include(x => x.Bumper)
.Include(x => x.Windows);
}
public static IQueryable<Engine> BuildEngine(this IQueryable<Engine> query) {
return query.Include(x => x.Pistons)
.Include(x => x.Cylendars);
}
//Or to handle a collection e.g.
public static IQueryable<Wheel> BuildWheel(this IQueryable<Wheel> query) {
return query.Include(x => x.Rim)
.Include(x => x.Tire);
}
Aquí hay otro hilo muy similar en caso de que sea útil para cualquier otra persona en esta situación, pero todavía no se maneja la posibilidad de realizar llamadas relacionadas con los métodos de extensión.
Entidad framework linq query Include () múltiples entidades hijas
Tuve este mismo problema y vi el otro enlace que mencionaba un atributo Include
. Mi solución asume que creó un atributo llamado IncludeAttribute
. Con el siguiente método de extensión y método de utilidad :
public static IQueryable<T> LoadRelated<T>(this IQueryable<T> originalQuery)
{
Func<IQueryable<T>, IQueryable<T>> includeFunc = f => f;
foreach (var prop in typeof(T).GetProperties()
.Where(p => Attribute.IsDefined(p, typeof(IncludeAttribute))))
{
Func<IQueryable<T>, IQueryable<T>> chainedIncludeFunc = f => f.Include(prop.Name);
includeFunc = Compose(includeFunc, chainedIncludeFunc);
}
return includeFunc(originalQuery);
}
private static Func<T, T> Compose<T>(Func<T, T> innerFunc, Func<T, T> outerFunc)
{
return arg => outerFunc(innerFunc(arg));
}