Является ли Агрегат смертельно ошибочным, потому что каждое в предложение выполняется отдельно?

Является ли 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 до .

Ответ 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 для объектов.