C# 实体框架及;Linq性能问题
在对产品对象列表进行分页时,Entity Framework和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
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]