当我运行模型映射时,一家公司有很多成员,例如405,000名成员。
var ErrorStack = String()
Thread.callStackSymbols.forEach {
print($0)
ErrorStack = "\(ErrorStack)\n" + $0
}
当我运行SQL查询时,需要几毫秒。在ASP.NET MVC,EF6 C#中,一个列表视图控制器命中最多可能需要10分钟。想法?
公司是我的域模型实体,MembershipUser是使用实体框架6的公共虚拟虚拟(FK),而不是C#6
当我在我的CompanyController(MVC)中并且我要求公司列表时,我得到一个没有包含公司计数的列表。当我对我的模型执行viewModelMapping以准备传递给视图时,我需要添加计数,并且无权访问上下文或数据库等。
viewModel.EmployeeCount = company.MembershipUser.Count(x => x.Deleted == false);
CompanyListToCompanyViewModel将公司列表映射到我的ViewModel列表,并在那里进行计数(MembershipUsers)。
我还尝试将count属性添加到公司DomainModel,例如:
// Redisplay list of companies
var viewModel = CrmViewModelMapping.CompanyListToCompanyViewModel(pagedCompanyList);
但是对于拥有大量员工的公司来说也需要很长时间。
这几乎就像我希望这是我的SQL查询:
public int EmployeeCount
{
get
{
// return MembershipUser.Where(x => x.Deleted == false).Count();
return MembershipUser.Count(x => x.Deleted == false);
}
}
但是早在我假设我可以让EF延迟加载和subQueries完成工作。但大量的开销正在扼杀我。在小型数据集上,我看不出真正的区别,但一旦计数变大,我的网站就无法使用。
答案 0 :(得分:1)
当您访问导航属性并使用count方法时,您将实现所有MembershipUser
表并使用C#进行过滤。
此命令中有三个操作:C#转到数据库并执行查询,将查询结果转换为C#对象列表(materialize)并执行过滤器(x => x.Deleted == false)in这个清单。
要解决此问题,您可以在MembershipUser DbSet中执行过滤:
Db.MembershipUser.Count(x => x.Deleted == false && companyId == company.Id);
使用DbSet进行查询,过滤器将在数据库中完成,而不会实现所有405000行。