2011-04-14 28 views
5

tengo una consulta sencilla que quiero hacer la siguiente manera:Marco de la entidad Eager carga del filtro

1) Products tienen ChildProducts que tienen PriceTiers
2) Quiero obtener toda la Products que tienen un Category con un ID de 1 y Display = verdadero.
3) Quiero incluir todos los ChildProducts que tienen Display = verdadero.
4) Y luego incluir el PriceTiers que tiene IsActive = verdadero.

De lo que he leído, EF no soporta Eager Cargando con filtros, por lo que el siguiente no funcionará:

ProductRepository.Query.IncludeCollection(Function(x) x.ChildProducts.Where(Function(y) y.Display).Select(Function(z) z.PriceTiers.Where(Function(q) q.IsActive))).Where(Function(x) x.Categories.Any(Function(y) y.ID = ID))) 

¿Alguna sugerencia?

+0

¿por qué usted comienza varias preguntas para el mismo problema? Además, ¿por qué lo haces una y otra vez? –

Respuesta

9

inicio de abajo hacia arriba, es decir, aplicar el filtro en el objeto PriceTier y sus padres, e incluir sus padres (C# lo siento, pero espero que usted consigue el punto):

repository.PriceTiers 
    .Include("ChildProduct.Product") // eager load parents 
    .Where(priceTier => 
    priceTier.IsActive && 
    priceTier.ChildProduct.Display && 
    priceTier.ChildProduct.Product.ID == 1 && 
    priceTier.ChildProduct.Product.Display) 
    .AsEnumerable() // execute SQL statement 
    .Select(priceTier => 
    priceTier.ChildProduct.Product) // return products rather than price tiers 

(Nota: priceTier => en C# es el mismo que Function(priceTier) en VB.NET)

MergeOption idealmente se debe establecer en algo otra que NoTracking al ejecutar la consulta. De lo contrario, EF no se asegurará de que un objeto que aparece varias veces en el conjunto de resultados de la consulta sólo se materializa una vez, tal como un Product o ChildProduct:

resultados no deseados: PriceTier 1 y 2 tienen los mismos padres , pero los padres se han materializado varias veces, una vez por cada PriceTier.

  • Producto 1
    • ChildProduct 1
      • PriceTier 1
  • Producto 1
    • ChildProduct 1
      • PriceTi er 2

resultados ideales: Establecer MergeOption distinto de NoTracking nada para obtener estos resultados:

  • producto 1
    • ChildProduct 1
      • PriceTier 1
      • PriceTier 2
+0

comenzando de abajo hacia arriba tendría un efecto secundario que si los padres existen que no tienen hijos que coincidan con los filtros, esos padres no estarán en el conjunto de resultados. podría usar una combinación izquierda para lograr su filtrado –

+1

Más de 5 años después, este sigue siendo un problema con EF y su respuesta sigue siendo la mejor. ¡Gracias! – urig

0

aquí es una solución que le dará a sus 'filas' para que coincida con su solicitud mediante el uso de izquierda se une en lugar de cargar con ganas, y que incluye filas primarias donde no hay filas hijo existen para los filtros

var query = from product in Products 
       join child_ in ChildProducts on product equals child_.Product into child_join 
       from child in child_join.DefaultIfEmpty() 
       join tier_ in PriceTiers on child equals tier_.ChildProduct into tier_join 
       from tier in tier_join.DefaultIfEmpty() 
       where product.Display && product.Category.ID == 1 
       where child == null || child.Display 
       where tier == null || tier.IsActive 
       select new {product, child, tier}; 
Cuestiones relacionadas