Преимущества
Преимущества SQL в хранимой процедуре:
- абстракция, вы можете реорганизовать базу данных без изменения приложения .net
- безопасность, вы могли бы улучшить проверку безопасности, установив правильные права на выполнение. Также вы можете ограничить набор данных, чтобы информация о безопасности не выводилась.
- прозрачность: какие запросы выполняются к базе данных?
- оптимизация запроса, использование правильного индекса и т. Д.
Downsides
Недостатки динамического SQL в хранимых процедурах:
Динамический SQL (на сервере SQL) может быть сложен с безопасностью и производительностью.
Безопасность
SQL-сервер имеет меньше «инструментов» для предотвращения внедрения. Переменные нельзя использовать повсеместно, и поэтому, если вы жестко закодируете весь порядок по опциям, тогда вы в безопасности. Но с динамической фильтрацией это может быть сложно.
например. это безопасно:
posts = context.Posts
.FromSql("SELECT * FROM mytable")
.OrderByDescending(p => p.CreateDate)
Это небезопасно (да, есть лучшие способы написать это):
declare varchar(200) @orderby = 'createDate DESC'
SET @sqlCommand = 'SELECT * FROM mytable ORDER by + '@orderby
EXEC (@sqlCommand)
Так что вам нужно перечислить все опции или проверить все опции.
Производительность
В отношении производительности могут быть проблемы с динамическим SQL в хранимых процедурах. Хранимая процедура, которая возвращает очень динамические данные,
мог выбрать неправильный план запроса с субоптимальной производительностью.
*
Вы можете перекомпилировать каждый вызов хранимой процедуры, но это также имеет свои недостатки.
Табличные значения функций
Другой вариант - использовать функции табличных значений (TVF). Они более ограничены, чем хранимые процедуры, но они возвращают таблицу, которую вы могли бы просмотреть и отсортировать.
Они имеют преимущества хранимых процедур, как описано выше, но не имеют недостатков динамического SQL в базе данных!
См. https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/linq/how-to-use-table-valued-user-defined-functions
Пример TVF и EF Core
Есть хороший пример функций табличных значений и EF,
.NET Core с TFV GetMatchingPostByTitle
posts = context.Posts
.FromSql("SELECT * FROM dbo.GetMatchingPostByTitle({0})", searchTerm)
.Where(p => p.BlogId == 1)
.OrderByDescending(p => p.CreateDate)
.ToList();
Сгенерирует этот SQL:
Подробнее здесь