#c# #linq #entity-framework-core
#c# #linq #entity-framework-core
Вопрос:
Я отправляю IQueryable методу, который анализирует данные для таблиц данных jQuery. Он создает фильтр из данных ФОРМЫ и создает оператор 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:
По-видимому, один из дефектов / багов перевода запросов 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();