Я бы принял прагматический подход - исторически главное «преимущество» хранения бизнес-логики в хранимых процессах заключается в соображениях производительности (архитектура 2,5 уровня), в то время как разделение бизнес-логики на уровень BLL (уровень 3 / N) обычно чище от перспективы технического обслуживания, и легче тестировать (макет / заглушка доступа к данным).
Однако, учитывая, что .NET ORMS с поддержкой LINQ, такие как LINQ2SQL, EF и NHibernate, теперь создают параметризованные SQL-запросы, где планы запросов могут кэшироваться, экранироваться для SQL-инъекций и т. Д., Я думаю, что переход к 3 / N-уровневой архитектуре более привлекательным, чем когда-либо, и большинства SPROC (особенно ориентированных на запросы) можно вообще избежать. Шаблоны репозитория в .NET обычно предоставляют параметры дерева выражений IQueryable / accept, что обеспечивает безопасный тип, но в то же время гибкий доступ к вашим таблицам. (Лично в архитектурах типа SOA я бы не стал раскрывать IQueryable за пределами BLL, т. Е. Ваши уровни Service и Presentation должны работать с четко определенным набором методов. Причина в том, что в противном случае вы никогда не сможете полностью протестировать свою систему, и вы выиграли ».
Тем не менее, в приличной системе всегда будет несколько исключений, когда действительно требовательный к данным фрагмент кода может все еще быть записан как сохраненный процесс по соображениям производительности. В этих случаях я оставляю SPROC и открываю SPROC через ORM, но все равно представляю функцию как метод сквозного доступа для вашего BLL.