Entity Framework Count с фильтром на поле очень медленно - большое количество - PullRequest
0 голосов
/ 26 мая 2018

Когда я запускаю сопоставление моделей, в одной компании много участников, например 405 000.

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

Когда я запускаю SQL-запрос, это занимает несколько миллисекунд.В ASP.NET MVC, EF6 C # это может занять до 10 минут для одного нажатия контроллера представления списка.Мысли?

Компания - это моя модель доменной модели, а MembershipUser - это общедоступная виртуальная виртуальная машина (FK), использующая структуру 6 сущностей, а не C # 6

Когда я в моем CompanyController (MVC)и я прошу список компаний, я получаю список без учета компании.Когда я делаю viewModelMapping для моей модели, чтобы подготовиться к передаче в представление, мне нужно добавить счетчик, и у меня нет доступа к контексту или БД и т. Д.

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

CompanyListToCompanyViewModel отображает списоккомпании в список моей ViewModel и делает счет (MembershipUsers) там.

Я также пытался добавить свойство count в DomainModel компании, например:

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

Но это также занимает много времени в компаниях с большим количеством сотрудников.

Как будто я хочу, чтобы это был мой SQL-запрос:

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

Но вначале я просто предположил, что могу позволить ленивой загрузке EF и выполнению подзапросов.но большие расходы убивают меня.В небольших наборах данных я не вижу реальной разницы, но как только счет увеличится, мой сайт станет непригодным для использования.

1 Ответ

0 голосов
/ 27 мая 2018

Когда вы обращаетесь к свойству навигации и используете метод count, вы материализуете всю таблицу MembershipUser и выполняете фильтр в C #.

В этой команде есть три операции: C # перейти кбазы данных и выполнить запрос, преобразовать результат запроса в список объектов C # (материализовать) и выполнить фильтр (x => x.Deleted == false) в этом списке.

Для решения этой проблемы вы можете сделатьфильтр в DbSet для MembershipUser:

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

При выполнении запроса с использованием DbSet фильтр будет выполняться в базе данных без материализации всех 405000 строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...