2010-08-29 22 views
8

Tengo una solución en la que he creado entidades de auto-seguimiento usando las plantillas RTM. He dividido las entidades y el contexto entre 2 proyectos para poder reutilizar las definiciones de tipo ya que planeo ejecutar el cliente/servidor a través de WCF.Entity Framework 4: Eager Loading (Include) con filtros usando Self Tracking Entities

Uno de mis métodos de servicio es necesario para devolver un gráfico de objetos "Producto" con objetos secundarios de "ProductSku" y estos a su vez tienen objetos secundarios de "ProductPrice". Los criterios de selección estarán en la propiedad "Nombre" del objeto "Producto" y en la propiedad "FinancialPeriodID" del "ProductPriceObject". Por ahora, no incluyo el nombre en la búsqueda, pero estoy teniendo problemas para regresar el gráfico.

Si sólo tiene que realizar la siguiente consulta (nota, esta sintaxis se toma de LINQPad en lugar del código de la aplicación real) ...

from product in Products.Include("Skus.PriceHistory") 
select product 

... entonces soy capaz de recuperar el gráfico de objetos completa para los artículos que requiero, por supuesto en este momento no hay filtro.

Si por el contrario, les presento el filtro de la siguiente manera ...

from product in Products.Include("Skus.PriceHistory") 
join sku in ProductSkus on product.ID equals sku.ProductID 
join price in ProductPrices on sku.ID equals price.ProductSkuID 
where price.FinancialPeriodID == 244 
select product 

... lo que estoy esperando para volver son los objetos "producto", el niño objetos "productSku" (que se encuentran en la colección "Skus" del "Producto") y sus objetos "ProductPrice" (que están en la colección "PriceHistory" del "ProductSku"), pero solo recupero los objetos "Product", la colección "Skus" es vacío.

También he tratado de codificación de la consulta como ...

from product in Products.Include("Skus.PriceHistory") 
from sku in product.Skus 
from price in sku.PriceHistory 
where price.FinancialPeriodID == 244 
select product 

... pero esto no hace ninguna diferencia tampoco.

Claramente, debo estar haciendo algo mal. ¿Alguien puede arrojar algo de luz sobre lo que es ese algo, como lo he estado haciendo durante algunas horas dando vueltas en círculos?

Respuesta

1

Editar:

¿Qué hay de:

from product in Products.Include("Skus.PriceHistory") 
where product.Skus.Any(s => s.PriceHistory.Any(p => p.FinancialPeriodID == 244)) 
select product 

Include ya se lleva a cabo todas las tareas necesarias para solventar las propiedades de navegación se une de manera adicional para los que no se necesitan condiciones. Lo que es aún más importante, cualquier combinación o proyección manual cambiará la forma de la consulta y no se usará Include.

También tenga en cuenta que donde la condición solo filtra productos. No filtrará los datos cargados por Incluir: obtendrá todos los productos con al menos un sku que tenga historial de precios con el ID del período financiero 244, pero esos productos tendrán cargados todos los skus y los historiales de precios. EF actualmente no admite filtrar en incluir. Si necesita relaciones filtradas también, debe ejecutar consultas separadas para obtenerlas.

+0

lo sentimos, "SKU" y "PriceHistory" son ambas colecciones, por lo que no es posible navegue todo el camino hacia abajo en una sola instrucción. Me temo que no hay más opción que incluir las uniones usando la unión o la de, como se muestra en los dos ejemplos. Gracias de todos modos. –

+0

Esto podría no haber ayudado a @MartinRobins, ¡pero me ayudó en mi propio proyecto! +1 Esta sintaxis funcionó para mí (tal vez una configuración totalmente diferente a la pregunta original, no sé ...) – BenSwayne

1

Tal vez la proyección puede hacer este truco?

Tome un vistazo a Linq filter collection with EF

+0

Gracias, pero realmente quiero minimizar el número de tipos de objetos que estoy pasando. Ya tengo un tipo de "Producto" perfectamente bueno, solo quiero que la carga ansiosa funcione correctamente para que los objetos secundarios se llenen. –

-1

Entidades de seguimiento no están habilitadas para realizar la carga diferida. Es por eso que la colección no está vacía con la generación de entidad predeterminada y no con STE. De hecho, su inclusión nunca carga entidades relacionadas si las usa en la consulta. Ahora su consulta L2E no es correcta.Creo que desea hacer algo como esto:

Espero que ayude

Matthieu

+0

No estoy tratando de usar carga lenta; Estoy tratando de usar la carga ansiosa. Si elimino la cláusula where o la base solo en el objeto de nivel superior, obtengo todos los objetos correctamente. Solo cuando uso la cláusula where en función de las propiedades de los objetos secundarios, se ignora el "Incluir". –

+0

Hola Martin, has encontrado una solución, tengo el mismo problema – freddoo

0

Tener incluir no es una garantía de tener la carga ansiosa y se podía pasar por alto en silencio por lo siguiente razón. Se explica mejor en este hilo. Puede seleccionar manualmente la tabla que desea cargar, p.

var result = from product in Products.Include("Skus.PriceHistory") 
from sku in product.Skus 
from price in sku.PriceHistory 
where price.FinancialPeriodID == 244 
select new { p=product, pricehistory = product.Skus.PriceHistory}; 
var products = results.select(pph => pph.product); 

https://social.msdn.microsoft.com/Forums/en-US/76bf1f22-7674-4e1e-85d3-68d29404e8db/include-is-ignored-in-a-subquery?forum=adodotnetentityframework

  • incluir sólo se aplica a los artículos en los resultados de la consulta: los objetos que se proyectado en la operación más externa en la consulta.
  • El tipo de resultados tiene que ser un tipo de entidad.
  • La consulta no puede contener operaciones que cambian el tipo del resultado entre Incluir y la operación más exterior (es decir, un GroupBy() o un Select() operación que cambia el tipo de resultado)
  • El parámetro tomada por Incluir es un camino dot delimitado de navegación propiedades que tienen que ser navegable desde una instancia del tipo regresaron a la operación más exterior
Cuestiones relacionadas