Написать хранимые процедуры в Linq / Lambda (модульно-тестируемые, но производительные хранимые процедуры). Возможный? - PullRequest
2 голосов
/ 26 ноября 2008

Я создаю источник данных для модели отчетов (службы отчетов SQL Server). Отчеты требуют много объединений и вычислений (скажем, вычисление финансовых параметров, таких как деньги, потраченные на это, то есть сумма A против суммы B) ... все это включает подобъекты.

Для меня имеет смысл написать модульные тесты для этого кода (т. Е. Проходить сбор заказов, собирать информацию на основе бизнес-правил, подобъектов и т. Д.) Чтобы сделать это правильно, я ожидаю, что мой код будет выглядеть ок. как это

foreach (IOrder in Orders)
   foreach (IOrderLine in IOrder.Orderlines) 
     ...

   return ...

и затем проверьте возвращаемое значение.

Но этот код не является SQL, который будет использоваться в представлении отчетов ... конечно ... Так что я думаю, я мог бы подключить сборку .NET в базе данных. Проблема здесь, конечно, в производительности ... Я не хочу зацикливать все эти объекты в C # ... слишком медленно.

Так что, естественно, деревья Linq / Lambda / Expression кажутся мне ответом. Как мы знаем, когда вы выполняете Linq to SQL, создаются деревья выражений, а затем на их основе генерируется правильный SQL.

Итак, я мог бы написать свой код в Linq to Objects, используя лямбда-выражения, выполнить модульное тестирование этого кода на образцах коллекций (с выражениями, скомпилированными в .net) и повторно использовать тот же код, что и Linq to SQL, в хранимой процедуре DB, так что внутри SQL Server он будет генерировать правильный SQL для меня (как уже делает Linq to SQL) ...

Тогда я мог бы воспользоваться преимуществами как модульных тестов, так и написания логики кода домена в C # и высокопроизводительных хранимых процедур для отчетов.

возможно? Могу ли я использовать Linq / Lambda в хранимых процедурах CLR SQL Server? Кто-нибудь делал или знает, как заставить это работать? Я сумасшедший? Вы знаете лучший способ сделать это?

Спасибо

P.S. Я думаю, теперь я понял, как это должно быть сделано правильно . По словам Уди Дахана, если я правильно его понимаю. База данных должна быть денормализована, а все рассчитанные поля должны быть на объектах в таблице. Когда что-то происходит с подобъектом (добавлен OrderLine), мой объект Customer должен получить событие и пересчитать интеллектуальное значение (кэшировать его и сохранить).

Тогда отчеты идут прямо, без логики и работают быстро ...

Ответы [ 2 ]

1 голос
/ 03 декабря 2008

Итак, я мог бы написать свой код в Linq для Объекты, использующие лямбда-выражения, модульное тестирование этого кода на образце коллекции (имеющие выражения скомпилировано в .net), и повторно использовать то же самое код как Linq to SQL хранится в БД процедура, так что внутри SQL Server это будет генерировать правильный SQL для меня (как уже делает Linq to SQL) ...

Этот план был в порядке, пока вы не предложили вызывать код CLR из ваших сохраненных процедур. Запуск кода CLR из самого процесса базы данных создает много проблем в отношении управления версиями, конфигурации и стабильности базы данных ... Слишком много проблем, если вы это сделаете.

Ваша мотивация состояла в том, чтобы иметь преимущество использования хранимых процедур, которые в целом быстрее. Если эти хранимые процессы в свою очередь выполняют код CLR, они не будут работать быстрее, чем код CLR, выполняемый в локальном процессе.

Использование сгенерированных выражений LINQ технически потребляет больше циклов ЦП, чем хранимых процедур. Это связано с тем, что ядру базы данных приходится заново генерировать план выполнения при каждом запуске запроса. Обычно ваш сервер базы данных находится на отдельной машине, хотя он не связан с процессором (вместо этого он будет ограничен емкостью диска или сети), так что это не является реальной проблемой производительности. Это может произойти, если вы запускаете сервер базы данных на той же машине, что и все остальное, но не пытайтесь исправить это с помощью чего-то столь запутанного, пока это не станет настоящей проблемой.

Предложение Уди может быть уместным, если вы хотите уменьшить накладные расходы на генерацию отчетов. Есть два важных побочных эффекта, которые следует рассмотреть в первую очередь. Во-первых, может ли позволить себе увеличить накладные расходы на производительность операций, которые порождают представленные поля? Большая проблема заключается в том, что она связывает вашу логику отчетности с кодом, который запускает целевую систему. Это предотвращает возможность обновления кода отчетности без обновления бизнес-кода и предполагает, что код отчета будет запущен сразу после ввода в эксплуатацию кода.

1 голос
/ 03 декабря 2008

Нет, нельзя использовать LINQ / Lambda в процессах SQL CRL - он основан на другой версии .NET и не поддерживает эти пространства имен.

...