Оператор Linq с проекцией на класс THEN GroupBy приводит к локальной оценке - PullRequest
1 голос
/ 31 марта 2019

Я отправляю IQueryable методу, который анализирует данные для jQuery DataTables.Он создает фильтр из данных FORM и создает оператор LINQ с фильтром, сортировкой, разбиением на страницы и т. Д., Который отправляется обратно на страницу в виде JSON.Я хотел бы расширить парсер и добавить итоги в набор результатов.Когда я добавляю оператор GroupBy, запрос оценивается не на сервере, а локально.Он будет выполняться на сервере, только если исходный IQueryable имеет анонимную проекцию ...

Это веб-сайт .Net Core 2.1.Я знаю, что в прошлом GroupBy не мог выполняться локально, но в 2.1.Я пробовал проекцию с классом и анонимным типом, и он правильно работает только с анонимным типом.Мне действительно нужно иметь возможность сделать это с помощью класса.

Следующее iQueryable отправляется парсеру:

var query = Context.InvoiceHeaders
     .AsNoTracking()
     .Where(x=>x.Slsno.Equals("13"))
     .Select(x => new InvoiceHeaderSummary()
     {
         SalesNumber = x.Slsno,
         OrderNumber = x.Ordnum,
         ItemAmount = x.Itmamt,
         SpecialChargeAmount = x.Sc1amt,
         TaxAmount = x.Taxamt,
         InvoiceTotal = x.Invamt
     })

var parser = new Parser<InvoiceHeaderSummary>(Request.Form, query);

Я пытаюсь расширить парсер, добавив списокитоги на выходе.Но поскольку я отправляю IQueryable с проекцией класса (InvoiceHeaderSummary), он не выполняется на сервере.Я получаю предупреждение о том, что он оценивается локально:

var totalList = query
     .GroupBy(i => 1)
     .Select(g => new
     {
          TotalInvoice = g.Sum(i => i.InvoiceTotal)
     })
     .ToList();

Я попытался создать весь встроенный метод LINQ, и он работает правильно (обратите внимание, что я использую анонимную проекцию до GroupBy, а не класса InvoiceHeaderSummary):

var query = Context.InvoiceHeaders
     .AsNoTracking()
     .Where(x=>x.Slsno.Equals("13"))
     .Select(x => new
     {
         SalesNumber = x.Slsno,
         OrderNumber = x.Ordnum,
         ItemAmount = x.Itmamt,
         SpecialChargeAmount = x.Sc1amt,
         TaxAmount = x.Taxamt,
         InvoiceTotal = x.Invamt
     })
     .GroupBy(i => 1)
     .Select(g => new
     {
          TotalInvoice = g.Sum(i => i.InvoiceTotal)
     })
     .ToList();

Есть ли способ правильно написать это, чтобы он работал оптимально ??

1 Ответ

1 голос
/ 31 марта 2019

Очевидно один из дефектов / ошибок перевода запросов EF Core 2.x.

Единственный найденный мной обходной путь - использовать перегрузку GroupBy с селектором элементов и выбрать данные, которые вы хотите объединитьв анонимный тип:

var totalList = query
     .GroupBy(i => 1, i => new { i.InvoiceTotal }) // <--
     .Select(g => new
     {
          TotalInvoice = g.Sum(i => i.InvoiceTotal)
     })
     .ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...