关于c#:实体框架计数,字段上的过滤器确实很慢 – 大数

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方法时,您将实现所有MembershipUser表并在c_中执行筛选。

此命令中有三个操作:C转到数据库并执行查询,将查询结果转换为C对象列表(物化),然后在此列表中执行筛选器(x=>x.deleted==false)。

要解决此问题,可以在membershipuser数据库集中执行筛选器:

1
Db.MembershipUser.Count(x => x.Deleted == false && companyId == company.Id);

使用dbset进行查询时,将在数据库中完成筛选,而不具体化所有405000行。