C# 实体框架4中的Linq查询。糟糕的表演

C# 实体框架4中的Linq查询。糟糕的表演,c#,.net,entity-framework,orm,performance,C#,.net,Entity Framework,Orm,Performance,在我的项目中,我使用EntityFramework 4处理数据。我通过一个简单的查询发现了可怕的性能问题。当我在EF4生成的sql查询上查看分析器时,我感到震惊 我的实体数据模型中有一些表: 看起来很简单。我正在尝试从指定类别中选择具有所有相关导航属性的所有产品项 我写了这个LINQ查询: ObjectSet<ProductItem> objectSet = ...; int categoryId = ...; var res = from pi in objectSet.I

在我的项目中,我使用EntityFramework 4处理数据。我通过一个简单的查询发现了可怕的性能问题。当我在EF4生成的sql查询上查看分析器时,我感到震惊

我的实体数据模型中有一些表:

看起来很简单。我正在尝试从指定类别中选择具有所有相关导航属性的所有产品项

我写了这个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;
对于数据库中的7000条记录和指定类别中的~1000条记录,此查询的执行时间id约为10秒。看看这一点就不足为奇了:

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 ....***
嵌套在联接中选择。。。极坏的我试图更改LINQ查询,但得到了相同的SQL查询输出


使用存储过程的解决方案对我来说是不可接受的,因为我使用的是SQL Compact数据库。

您正在执行的是
包含(“产品”).Include(“库存”).Include(“库存.存储”)
,您想知道为什么要获取这么多记录,为什么要看到这么大的SQL查询?请确保您了解
Include
方法的内容。如果需要更简单的查询,请使用以下命令:

var res =
    from pi in objectSet
    where pi.Product.CategoryId == categoryId 
    select pi;

但是请注意,这可能会延迟加载
产品
库存
存储
,这可能会导致在迭代这些子集合时发送更多查询。

我认为问题在于存储元素中的库存集合。您的查询会将所选的产品、产品项和库存项限制为指定类别ID的产品、产品项和库存项。但是,为了填充存储元素的库存集合,查询还必须返回使用相同StorageId的所有库存行(然后返回这些附加库存记录的所有相应ProductItem和Product行)


首先,我要从存储元素中删除库存集合或删除相应的include。

你的英语还不错:)这个问题也很好+1您可以使用共享图像。包含哪些内容?为什么不直接从objectSet中的pi开始,其中pi.Product.CategoryId==CategoryId选择pi?如果使用手写SQL查询,性能是否更好?+1与手写SQL进行比较。很难知道SQL Compact的总体性能如何(我当然不知道)+1个优点-对于Product:ProductItem(1:*)和ProductItem:Inventory(1:*),单个产品将加载大量额外(可能不需要)的数据。。。。怪不得这么慢。。。。
var res =
    from pi in objectSet
    where pi.Product.CategoryId == categoryId 
    select pi;