我有3个表OPERATORS
(20条记录),SALES
(7000条记录),SALES_DETAIL
(36000条记录)。
在Visual Studio 2015中使用Entity Framework和数据库优先方法我想创建一个Web Api控制器,它只返回当前打开的销售(CLOSE_DATA==null
)的运算符:
public IQueryable <OPERATORS> GetOPERATORS()
{
IQueryable<OPERATORS> c = from co in db.SALES
join op in db.OPERATORS on co.ID_OP equals op.ID
where co.CLOSE_DATA == null
select op;
return c;
}
在SQL Server Management Studio中运行的等效SQL会返回正确的结果,在0.00毫秒内返回3条记录。
select o.*
from OPERATORS o
inner join SALES c on c.ID_OP = o.id
where c.CLOSE_DATA is null
在浏览器api控制器中返回大量数据并且浏览器几乎冻结,在fiddler中答案非常慢,我可以看到SALES_DETAIL
中我没有包含在我的查询中的数据?
如果我更改控制器中的操作以返回Long
并返回c.Count()
,则结果是正确的:3。
为什么包含SALES_DETAIL
,为什么查询非常慢?
谢谢!
答案 0 :(得分:2)
您可以在此处尝试2个选项。
选项1:您可以停用 lazy loading
whole project
,如下所示。
public YourContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
选项2 关闭 lazy loading
以获取特定的导航属性,如下所示。通过制作SaleDetails
属性non-virtual
public class YourModel
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<SaleDetail> SaleDetails { get; set; }
}
以下是一个有用的链接:Lazy Loading
答案 1 :(得分:1)
您可以通过添加AsNoTracking优化/改进您的查询:
实体框架提供了许多性能调优选项,可帮助您优化应用程序的性能。其中一个调整选项是.AsNoTracking()
所以你的查询将如下所示:
var query = from co in db.SALES.AsNoTracking()
join op in db.OPERATORS.AsNoTracking()
on co.ID_OP equals op.ID
where co.CLOSE_DATA == null
select op;
return query.ToList();
要使该呼叫无阻塞,您可以利用EF中的异步调用:
public async Task<IList<OPERATORS>> GetOPERATORS()
{
var query = from co in db.SALES.AsNoTracking()
join op in db.OPERATORS.AsNoTracking()
on co.ID_OP equals op.ID
where co.CLOSE_DATA == null
select op;
return await query.ToListAsync();
}