Является ли Агрегат смертельно ошибочным, потому что каждое в предложение выполняется отдельно?
Является ли VB.NET Aggregate
запросом смертельно ошибочным при использовании в качестве первого (внешнего) предложения выражения Linq с несколькими предложениями Into
, потому что каждое предложение Into
выполняется отдельно?
"Очевидный" ответ SELECT MIN(ZoneMin), MAX(ZoneMin) FROM Plant
в LINQ to SQL -
Dim limits = Aggregate p In Plants Select p.ZoneMin Into Min(), Max()
Однако этот ответ фактически извлекает каждый из Min
и Max
(и если вы включаете другие агрегированные функции, такие как Count
и Average
) в отдельные SQL-запросы. Это можно легко увидеть в LINQPad.
Есть ли транзакция (или что-то другое, делающая эти запросы атомарными), не показанные LINQPad, или это состояние гонки, ожидающее своего существования? (И поэтому вам нужно сделать трюки, указанные в ответе на вышеупомянутый вопрос, для принудительного единственного запроса, который возвращает несколько агрегатов.)
Итак, существует ли запрос LINQ-to-SQL с помощью Aggregate
, который возвращает несколько агрегатных функций в одном (или, по крайней мере, "атомарном" ) запросе?
<суб > (Я также говорю "очевидный", потому что очевидный ответ мне, Aggregate p In Plants Into Min(p.ZoneMin), Max(p.ZoneMin)
, фактически извлекает всю таблицу дважды, даже когда оптимизирован, а затем использует Linq-to-Entities Min
и Max
для получения результата: -()
Я думал, что Aggregate
не является VB-специфичным, но похоже, что у С# нет этого выражения запроса, поэтому я изменил сообщение .net до vb.net.
Ответы
Ответ 1
Чтобы ответить на мой более широкий вопрос: Aggregate
сломан для создания отдельных SQL-запросов без транзакций?
Все LINQ могут привести к тому, что если вы не будете тщательно корректировать свои запросы, чтобы привести только к одному SELECT
, и это может быть невозможно, без "отказа", получения большего результата в одном запросе и затем используя Linq-to-Objects для агрегирования или иным образом манипулирования данными. Например, этот "запрос" .
Так что, в общем, до программиста, чтобы транзакции были добавлены вокруг запросов LINQ, которые могут вызывать несколько запросов. Нам просто нужно знать наверняка, какие запросы LINQ могут трансформироваться в несколько SQL-запросов.
Ответ 2
Хотя он не использует ключевое слово Aggregate, вы можете выполнять несколько функций в одном запросе, используя следующий синтаксис:
Dim query = From book In books _
Group By key = book.Subject Into Group _
Select id = key, _
BookCount = Group.Count, _
TotalPrice = Group.Sum(Function(_book) _book.Price), _
LowPrice = Group.Min(Function(_book) _book.Price), _
HighPrice = Group.Max(Function(_book) _book.Price), _
AveragePrice = Group.Average(Function(_book) _book.Price)
Однако, похоже, проблема с реализацией предложения Aggregate. Рассмотрим следующий запрос от Northwind:
Aggregate o in Orders
into Sum(o.Freight),
Average(o.Freight),
Max(o.Freight)
Это вызывает 3 запроса базы данных. Первые два выполняют отдельные агрегированные предложения. Третий возвращает всю таблицу обратно клиенту и выполняет Max на клиенте с помощью Linq для объектов.