C# 实体框架及;Linq性能问题

C# 实体框架及;Linq性能问题,c#,linq,performance,entity-framework,C#,Linq,Performance,Entity Framework,在对产品对象列表进行分页时,Entity Framework和Linq存在性能问题: var data =_service.GetAll(); var page = data.Skip((index) * pageSize).Take(pageSize); list.Add(page.AsEnumerable); // ** its slow right here 在我的测试数据库中有1958个产品,但是当上面的代码运行时,我可以看到3916(即1958*2)个单独的查询被执行(通过查看sq

在对产品对象列表进行分页时,Entity Framework和Linq存在性能问题:

var data =_service.GetAll(); 
var page = data.Skip((index) * pageSize).Take(pageSize);
list.Add(page.AsEnumerable); // ** its slow right here
在我的测试数据库中有1958个产品,但是当上面的代码运行时,我可以看到3916(即1958*2)个单独的查询被执行(通过查看sql分析器)

Product类类似于:

public class Product 
{
    public virtual int Id {get;set;}
    public virtual string ProductCode {get;set;}
    //..etc other properties
    public virtual ICollection<WarehouseProduct> WarehouseProducts { // etc }
    public virtual ICollection<InvoiceLine> InvoiceLines { // etc }
    // etc other navigation properties
}

我做错了什么?产品对象有12个不同的导航属性,但只有WarehouseProduct被查询了3916次。请注意,该查询中没有WHERE子句,但两个表之间存在外键关系(这就是为什么它是一个导航属性)

您必须在获得产品后访问
Product.WarehouseProducts
,因此 如果您使用的是实体,则需要使用
产品。包括(“仓库产品”)。包括(“发票行”)
GetAll()
方法中,它将告诉实体在同一查询中检索数据


默认情况下,相关实体是延迟加载的,因此如果不使用
Include()
指定要在结果中包含哪些相关实体,则每次访问代码中的相关实体时,您将触发另一个数据库查找。

页面。AsEnumerable
将导致对查询的序列进行求值和具体化。前面的语句假设仍然启用延迟加载,并且您正在查询SQL数据源,正在设置组成要执行的SQL语句的条件

您没有发布GetAll()方法,因此这可能是其他记录的来源


生成的SQL查询应该有一个TOP作为select的一部分,并且它应该返回一个包含多条记录的结果集,因此您可能无法分析正确的查询。

您能向非EF专家解释一下这有什么帮助吗?我已经编辑了这个问题,以准确显示SQL查询发生的位置(此处标记为“**its slow”). 我根本没有访问Product.WarehouseProducts-这就是我无法理解所有查询的原因。你确定它执行了两次,而且你不仅仅是在看BeginExec/EndExec形式的重复行吗?谢谢,你是对的-它在配置文件中显示SQL:BatchStarting和SQL:BatchEnding,因此这是1958个查询。但是这仍然不能解释为什么它对每个产品都执行一次,并且没有任何where子句。你能发布GetAll方法的代码吗?是的,很难判断黑盒子中的实际查询发生了什么。
service.GetAll()
调用
repository.GetAll()
它只返回ObjectSet.AsQueryable()
SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[ProductId] AS [ProductId], 
// etc
FROM [dbo].[WarehouseProducts] AS [Extent1]