Dal*_*ser 0 linq asp.net entity-framework
match match = myRepo.GetAll()
.Where(m => m.personId == personId)
.Where(m => m.companyId == companyId).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
现在有超过100万条记录,需要很长时间.我重构它来做一个linq查询,它立即运行.这表明myRepo.GetAll()返回所有内容然后循环遍历每一行来执行where而不是在db级别执行.
GetAll看起来像这样:
public virtual IEnumerable<T> GetAll(Paging p = null)
{
// Get the set as a queryable.
IQueryable<T> q = _db.Set<T>();
if(p != null)
{
p.TotalCount = q.Count();
q = q.Skip(p.StartAt).Take(p.PageSize);
}
// Return the enumerable.
return q.AsEnumerable<T>();
}
Run Code Online (Sandbox Code Playgroud)
我只是想要理智地检查我的理论是否正确,有些人认为因为它的IEnumerable它不应该这样做,但它的返回首先必须在本地函数中循环,因为它在linq查询之外的地方.
您的GetAll方法返回IEnumerable<T>(而不是IQueryable<T>)的事实意味着您的Where调用使用LINQ to Objects,而不是EF.换句话说,该查询是在本地获取所有数据,并在您的过程中对其进行过滤.这不好.
考虑GetAll改为:
public virtual IQueryable<T> GetAll(Paging p = null)
{
// Get the set as a queryable.
IQueryable<T> q = _db.Set<T>();
if(p != null)
{
p.TotalCount = q.Count();
q = q.Skip(p.StartAt).Take(p.PageSize);
}
return q;
}
Run Code Online (Sandbox Code Playgroud)
然后你仍然在"可查询的土地".请注意,这仍然存在缺陷,因为您希望在任何其他查询之后应用分页,而不是之前.所以你可能真的想要一个方法返回_db.Set<T>(),然后有一个单独的扩展方法进行分页.(我很担心您的分页实现需要您计算完整的结果,请注意......)