简体   繁体   English

在字段上使用过滤器的实体框架计数非常慢-计数很大

[英]Entity Framework Count with a filter on field really slow - large count

When I am running a Model Mapping, one company has a lot of members, like 405,000 members. 当我运行模型映射时,一个公司有很多成员,例如405,000个成员。

viewModel.EmployeeCount = company.MembershipUser.Count(x => x.Deleted == false);

When I run the SQL query, it takes a few milliseconds. 当我运行SQL查询时,需要花费几毫秒的时间。 In ASP.NET MVC, EF6 C# this can take up to 10 minutes for one list view controller hit. 在ASP.NET MVC,EF6 C#中,一次击中列表视图控制器最多可能需要10分钟。 Thoughts? 思考?

Company is my Domain Model Entity, and MembershipUser is a public virtual virtual (FK) using entity framework 6, not C#6 Company是我的域模型实体,MembershipUser是使用实体框架6而非C#6的公共虚拟虚拟(FK)

When I'm in my CompanyController (MVC) and I ask for a company list, I get a list without the company count included. 当我在CompanyController(MVC)中并要求提供公司列表时,我得到的列表中未包含公司计数。 When I do a viewModelMapping to my Model to prep to pass to the view, I need to add the count, and do not have access to the context or DB, etc. 当我对模型进行viewModelMapping准备传递给视图时,我需要添加计数,并且无权访问上下文或数据库等。

            // Redisplay list of companies
            var viewModel = CrmViewModelMapping.CompanyListToCompanyViewModel(pagedCompanyList);

CompanyListToCompanyViewModel maps the list of companies to the list of my ViewModel and does the count (MembershipUsers) there. CompanyListToCompanyViewModel将公司列表映射到我的ViewModel列表,并在那里进行计数(MembershipUsers)。

I also tried adding the count property to the company DomainModel such as: 我还尝试将count属性添加到公司DomainModel中,例如:

public int EmployeeCount
    {
        get
        {
            // return MembershipUser.Where(x => x.Deleted == false).Count();
            return MembershipUser.Count(x => x.Deleted == false);
        }
    }

But it also takes a long time on companies with a lot of Employees. 但是,对于拥有大量员工的公司来说,这也需要花费很长时间。

It's almost like I want this to be my SQL Query: 几乎就像我希望它成为我的SQL查询一样:

Select *, (SELECT count(EmployeeID) as Count WHERE Employee.CompanyID = CompanyID) as employeeCount from Company

But early on I just assumed I could let EF lazy loading and subQueries do the work. 但是从一开始我就以为我可以让EF延迟加载和subQueries来完成工作。 but the overhead on large counts is killing me. 但是大量的开销使我丧命。 On small datasets I see no real difference, but once the counts get large my site is unsusable. 在小型数据集上,我看不出有什么真正的区别,但是一旦计数增加,我的网站就无法使用。

When you are accessing the navigation property and using the count method, you are materializing all the MembershipUser table and doing the filter in C#. 当您访问导航属性并使用count方法时,您将实现所有MembershipUser表并在C#中进行过滤。

There are three operations in this command: The C# go to the database and execute the query, transform the query result in C# object list (materialize) and execute the filter (x => x.Deleted == false) in this list. 此命令中包含三个操作:C#进入数据库并执行查询,将查询结果转换为C#对象列表(实现),然后执行此列表中的过滤器(x => x.Deleted == false)。

To solve this problem you can do the filter in the MembershipUser DbSet: 要解决此问题,您可以在MembershipUser DbSet中进行过滤:

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

Doing the query using the DbSet, the filter will be done in database without materialize all 405000 rows. 使用DbSet进行查询时,过滤器将在数据库中完成,而不会实现所有405000行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM