En mi proyecto estoy usando EntityFramework 4 para trabajar con datos. Encontré problemas de rendimiento horribles con una simple consulta. Cuando miré el generador de perfiles en una consulta sql, generada por EF4, me sorprendió.Consultas de Linq en Entity Framework 4. Horrible rendimiento
que tienen algunas mesas en mi modelo de datos entidad:
Se ve bastante simple. Intento seleccionar todos los artículos del producto de la categoría especificada con todas las propiedades de navegación relacionadas.
escribí esta consulta LINQ:
ObjectSet<ProductItem> objectSet = ...;
int categoryId = ...;
var res = from pi in objectSet.Include("Product").Include("Inventory").Include("Inventory.Storage")
where pi.Product.CategoryId == categoryId
select pi;
EF genera esta consulta SQL:
SELECT [Project1].[pintId1] AS [pintId],
[Project1].[pintId] AS [pintId1],
[Project1].[intProductId] AS [intProductId],
[Project1].[nvcSupplier] AS [nvcSupplier],
[Project1].[ nvcArticle] AS [ nvcArticle],
[Project1].[nvcBarcode] AS [nvcBarcode],
[Project1].[bIsActive] AS [bIsActive],
[Project1].[dtDeleted] AS [dtDeleted],
[Project1].[pintId2] AS [pintId2],
[Project1].[nvcName] AS [nvcName],
[Project1].[intCategoryId] AS [intCategoryId],
[Project1].[ncProductType] AS [ncProductType],
[Project1].[C1] AS [C1],
[Project1].[pintId3] AS [pintId3],
[Project1].[intProductItemId] AS [intProductItemId],
[Project1].[intStorageId] AS [intStorageId],
[Project1].[dAmount] AS [dAmount],
[Project1].[mPrice] AS [mPrice],
[Project1].[dtModified] AS [dtModified],
[Project1].[pintId4] AS [pintId4],
[Project1].[nvcName1] AS [nvcName1],
[Project1].[bIsDefault] AS [bIsDefault]
FROM (SELECT [Extent1].[pintId] AS [pintId],
[Extent1].[intProductId] AS [intProductId],
[Extent1].[nvcSupplier] AS [nvcSupplier],
[Extent1].[ nvcArticle] AS [ nvcArticle],
[Extent1].[nvcBarcode] AS [nvcBarcode],
[Extent1].[bIsActive] AS [bIsActive],
[Extent1].[dtDeleted] AS [dtDeleted],
[Extent2].[pintId] AS [pintId1],
[Extent3].[pintId] AS [pintId2],
[Extent3].[nvcName] AS [nvcName],
[Extent3].[intCategoryId] AS [intCategoryId],
[Extent3].[ncProductType] AS [ncProductType],
[Join3].[pintId1] AS [pintId3],
[Join3].[intProductItemId] AS [intProductItemId],
[Join3].[intStorageId] AS [intStorageId],
[Join3].[dAmount] AS [dAmount],
[Join3].[mPrice] AS [mPrice],
[Join3].[dtModified] AS [dtModified],
[Join3].[pintId2] AS [pintId4],
[Join3].[nvcName] AS [nvcName1],
[Join3].[bIsDefault] AS [bIsDefault],
CASE
WHEN ([Join3].[pintId1] IS NULL) THEN CAST(NULL AS int)
ELSE 1
END AS [C1]
FROM [ProductItem] AS [Extent1]
INNER JOIN [Product] AS [Extent2]
ON [Extent1].[intProductId] = [Extent2].[pintId]
LEFT OUTER JOIN [Product] AS [Extent3]
ON [Extent1].[intProductId] = [Extent3].[pintId]
LEFT OUTER JOIN (SELECT [Extent4].[pintId] AS [pintId1],
[Extent4].[intProductItemId] AS [intProductItemId],
[Extent4].[intStorageId] AS [intStorageId],
[Extent4].[dAmount] AS [dAmount],
[Extent4].[mPrice] AS [mPrice],
[Extent4].[dtModified] AS [dtModified],
[Extent5].[pintId] AS [pintId2],
[Extent5].[nvcName] AS [nvcName],
[Extent5].[bIsDefault] AS [bIsDefault]
FROM [Inventory] AS [Extent4]
INNER JOIN [Storage] AS [Extent5]
ON [Extent4].[intStorageId] = [Extent5].[pintId]) AS [Join3]
ON [Extent1].[pintId] = [Join3].[intProductItemId]
WHERE [Extent2].[intCategoryId] = 8 /* @p__linq__0 */) AS [Project1]
ORDER BY [Project1].[pintId1] ASC,
[Project1].[pintId] ASC,
[Project1].[pintId2] ASC,
[Project1].[C1] ASC
Para 7000 registros en la base de datos y ~ 1000 récord en la categoría especificada de tiempo de ejecución de esta consulta Identificación alrededor de 10 segundos . No es sorprendente que mira esto:
FROM [ProductItem] AS [Extent1]
INNER JOIN [Product] AS [Extent2]
ON [Extent1].[intProductId] = [Extent2].[pintId]
LEFT OUTER JOIN [Product] AS [Extent3]
ON [Extent1].[intProductId] = [Extent3].[pintId]
***LEFT OUTER JOIN (SELECT ....***
anidada seleccionar en unirse a ... horrible ... He intentado cambiar consulta LINQ, pero consigo misma consulta SQL emite.
Una solución que utiliza procedimientos almacenados no es aceptable para mí, porque estoy usando la base de datos SQL Compact.
Tu inglés no es tan malo :) Pregunta bien formada también. +1 – Aren
Puede usar http://imgur.com/ para compartir imágenes. – Steven
¿Qué pasa con los Incluye? ¿Por qué no simplemente _from pi en objectSet donde pi.Product.CategoryId == categoryId select pi_? –