Entity Framework Count with a filter on field really slow - large count
当我运行模型映射时,一个公司有很多成员,比如405000个成员。
1 | viewModel.EmployeeCount = company.MembershipUser.Count(x => x.Deleted == false); |
当我运行SQL查询时,需要几毫秒。在ASP.NET MVC、EF6 C中,点击一个列表视图控制器可能需要10分钟。思想?
公司是我的域模型实体,而membershipuser是使用实体框架6的公共虚拟(fk),而不是C_6
当我在我的公司控制器(MVC)中,我要求一个公司列表时,我得到一个不包括公司计数的列表。当我对模型执行ViewModelMapping以准备传递给视图时,我需要添加计数,并且不能访问上下文或数据库等。
1 2 | // Redisplay list of companies var viewModel = CrmViewModelMapping.CompanyListToCompanyViewModel(pagedCompanyList); |
CompanyListToCompanyViewModel将公司列表映射到我的ViewModel列表,并在其中进行计数(MembershipUsers)。
我还尝试将Count属性添加到Company DomainModel,例如:
1 2 3 4 5 6 7 8 | public int EmployeeCount { get { // return MembershipUser.Where(x => x.Deleted == false).Count(); return MembershipUser.Count(x => x.Deleted == false); } } |
但对于拥有大量员工的公司来说,这也需要很长的时间。
就像我希望这是我的SQL查询:
1 | Select *, (SELECT count(EmployeeID) as Count WHERE Employee.CompanyID = CompanyID) as employeeCount from Company |
但在早期,我只是假设我可以让ef延迟加载和子查询完成这项工作。但是,大量的开销让我很痛苦。在小数据集上,我看不到真正的区别,但一旦计数变大,我的网站就不可靠了。
当您访问navigation属性并使用count方法时,您将实现所有
此命令中有三个操作:C转到数据库并执行查询,将查询结果转换为C对象列表(物化),然后在此列表中执行筛选器(x=>x.deleted==false)。
要解决此问题,可以在membershipuser数据库集中执行筛选器:
1 | Db.MembershipUser.Count(x => x.Deleted == false && companyId == company.Id); |
使用dbset进行查询时,将在数据库中完成筛选,而不具体化所有405000行。