实体框架& Linq性能问题

时间:2010-09-01 04:59:19

标签: c# linq performance entity-framework

在分页Product对象列表时,我遇到了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 profiler)。

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
}

在sql profiler中,我可以看到此查询执行了3916次:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[ProductId] AS [ProductId], 
// etc
FROM [dbo].[WarehouseProducts] AS [Extent1]

我做错了什么? Product对象具有12种不同的导航属性,但仅查询了WarehouseProduct 3916次。请注意,该查询没有WHERE子句,但两个表之间存在外键关系(这就是导航属性的原因)

2 个答案:

答案 0 :(得分:3)

获得产品后,您必须访问Product.WarehouseProducts,所以 如果您使用的是实体,则需要使用Products.Include("WarehouseProduct").Include("InvoiceLine")GetAll()方法中,它会告诉实体在同一查询中检索数据。

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

答案 1 :(得分:0)

page.AsEnumerable导致查询序列被评估和具体化。前面的语句(假设仍然启用了延迟加载并且您正在查询SQL数据源)正在设置构成要执行的SQL语句的条件。

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

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