Я работаю в компании, которая использует только хранимые процедуры для всего доступа к данным, что очень раздражает, когда мы синхронизируем наши локальные базы данных, так как каждый коммит мы должны запускать новые процессы. Я использовал некоторые базовые ORM в прошлом, и я считаю, что опыт намного лучше и чище. Я хотел бы предложить менеджеру по разработке и остальным членам команды, что мы рассмотрим использование ORM некоторого вида для будущей разработки (остальная часть команды знакома только с хранимыми процедурами и никогда не использовала ничего другого). Текущая архитектура - .NET 3.5, написанная как .NET 1.1, с «богами», которые используют странную реализацию ActiveRecord и возвращают нетипизированные наборы данных, которые зациклены в файлах с выделенным кодом - классы работают примерно так:
class Foo {
public bool LoadFoo() {
bool blnResult = false;
if (this.FooID == 0) {
throw new Exception("FooID must be set before calling this method.");
}
DataSet ds = // ... call to Sproc
if (ds.Tables[0].Rows.Count > 0) {
foo.FooName = ds.Tables[0].Rows[0]["FooName"].ToString();
// other properties set
blnResult = true;
}
return blnResult;
}
}
// Consumer
Foo foo = new Foo();
foo.FooID = 1234;
foo.LoadFoo();
// do stuff with foo...
Практически нет применения каких-либо шаблонов дизайна. Там нет никаких тестов вообще (никто больше не знает, как писать модульные тесты, и тестирование выполняется через загрузку веб-сайта вручную и поиск по нему). Просматривая нашу базу данных, мы имеем: 199 таблиц, 13 представлений, колоссальные 926 хранимых процедур и 93 функции. Около 30 или около того таблиц используются для пакетных заданий или внешних вещей, остальные используются в нашем основном приложении.
Стоит ли вообще придерживаться другого подхода в этом сценарии? Я говорю о продвижении вперед только потому, что нам не разрешается рефакторинг существующего кода, так как «он работает», поэтому мы не можем изменить существующие классы для использования ORM, но я не знаю, как часто мы добавляем новые модули вместо добавление / исправление текущих модулей, поэтому я не уверен, является ли ORM правильным подходом (слишком много вложено в хранимые процедуры и наборы данных). Если это правильный выбор, как мне представить кейс для его использования? Вдобавок ко всему, единственное преимущество, которое я могу придумать, это иметь более чистый код (хотя это может и не быть, поскольку текущая архитектура не ' t построены с учетом ORM, поэтому в основном мы будем включать ORMs присяжных в будущие модули, но старые по-прежнему будут использовать наборы данных) и меньше хлопот, чтобы помнить, какие скрипты процедур были запущены и какие должны быть запущены, и т.д., но это все, и я не знаю, насколько убедительным будет такой аргумент. Ремонтопригодность - это еще одна проблема, но кажется, что никто, кроме меня, не обеспокоен.
источник
Ответы:
Хранимые процедуры плохие, они часто медленные и примерно такие же эффективные, как и обычный клиентский код.
[Ускорение обычно происходит из-за того, как спроектирован интерфейс клиента и хранимой процедуры, и из-за того, что транзакции записываются в виде коротких, сфокусированных пакетов SQL.]
Хранимые процедуры являются одним из худших мест для размещения кода. Он разбивает ваше приложение на два языка и платформы в соответствии с правилами, которые часто бывают случайными.
[Этот вопрос будет оценен как -30, потому что многие, многие считают, что хранимые процедуры обладают магической силой и должны использоваться, несмотря на проблемы, которые они вызывают.]
Перемещение всего кода хранимой процедуры на клиент значительно упростит задачу для всех.
Вам все равно придется время от времени обновлять схему и модель ORM. Однако изменения схемы изолированы от изменений ORM, что обеспечивает некоторую независимость между приложениями и схемой базы данных.
Вы сможете тестировать, исправлять, поддерживать, понимать и адаптировать все эти хранимые процедуры по мере их переписывания. Ваше приложение будет работать примерно одинаково и станет гораздо менее хрупким, потому что вы больше не используете две разные технологии.
ORM не волшебство, и хорошие навыки проектирования баз данных абсолютно необходимы для его работы.
Кроме того, программы с большим количеством клиентского SQL могут работать медленно из-за плохого понимания границ транзакций. Одна из причин, по которым хранимые процедуры кажутся быстрыми, заключается в том, что хранимые процедуры требуют очень и очень тщательного проектирования транзакций.
ORM волшебным образом не навязывают тщательный дизайн транзакций. Проектирование транзакций все еще должно выполняться так же тщательно, как и при написании хранимых процедур.
источник
Хранимые процедуры хороши, они быстры и очень эффективны и являются идеальным местом для размещения вашего кода, связанного с данными. Перенос всего этого кода на клиент немного облегчит вам как разработчику клиента (немного, так как вам все равно придется обновлять схему и модель ORM, когда commit изменяет их), но вы потеряете весь этот существующий код и сделаете Ваше приложение медленнее и, вероятно, более хрупким, учитывая потерю всех этих навыков SQL.
Интересно, администраторы баз данных сидят там и говорят: «О, каждый коммит, мне нужно снова и снова сбрасывать клиента, вместо этого мы должны переместить весь код в формы БД».
В вашем случае вы сможете заменить существующий пользовательский ORM (т.е. ваши забавные классы) на чужой без каких-либо потерь, за исключением изменений в способе написания кода с выделенным кодом. Вы также можете оставить SP, так как большинство (все?) ORM с радостью их вызовят. Поэтому я бы рекомендовал заменить эти классы "Foo" на ORM и перейти оттуда. Я бы не рекомендовал заменять ваши SP.
PS. Похоже, у вас много общего кода в классах code-behind, что делает их шаблоном дизайна сами по себе. Как вы думаете, шаблон дизайна на первом месте! (хорошо, это может быть не самым лучшим или даже хорошим, но это все еще DP)
Изменить: и теперь с Dapper , любая причина, чтобы избежать sprocs над тяжелой ORM исчезла.
источник
ds.Tables[0].Rows[0]["FooName"].ToString()
дерьма. Менеджер любит хранимые процедуры? Он получает их. Но физически невозможно утверждать, что перемещение всего этого повторяющегося стандартного кода в нечто, сгенерированное, скажем, LINQ to SQL, было плохой вещью.Похоже, вы пытаетесь вывести свою команду из одной крайности (хранимые процедуры и наборы данных) в другую (полноценный ORM). Я думаю, что есть и другие, более постепенные изменения, которые вы можете внести в реализацию для улучшения качества кода на уровне доступа к данным, которые ваша команда может с большей готовностью принять.
Выложенный вами полусгоревший код реализации активной записи не особенно удобен - я бы порекомендовал исследовать шаблон репозитория, который легко понять и реализовать, и который очень популярен среди разработчиков .NET. Этот шаблон часто ассоциируется с ORM, но создавать репозитории с помощью простого ADO.NET также просто.
Что касается DataSet's - гадость! С вашими библиотеками классов будет намного легче работать, если вы возвращаете статически (или даже динамически) типизированные объекты. Я считаю, что эта иллюстрация объясняет мое мнение о DataSet лучше, чем я мог.
Кроме того, вы можете отказаться от хранимых процедур, не переходя на ORM - нет ничего плохого в использовании параметризованного SQL. На самом деле, я бы определенно предпочел это использование хранимых процедур, если только у вас нет сложных процедур, которые экономят при многократных поездках на сервер. Я тоже ненавижу, когда открываю устаревшую базу данных и вижу бесконечный список процедур CRUD.
Я не препятствую использованию ORM - я обычно использую их в большинстве проектов, над которыми я работаю. Однако я понимаю, почему может быть много трений при попытке внедрить один в этот проект и вашу команду, которые, мягко говоря, звучат так, будто они перестали узнавать что-то новое около 8 лет назад. Сказав, что я определенно взгляну на новое поколение «микро-ORM», таких как Dapper (используется для питания этого сайта не меньше) и Massive , оба из которых невероятно просты в использовании и держат вас ближе к SQL, чем типичный ORM, и что ваша команда может быть более готова принять.
источник
Я нахожусь в подобной ситуации, на самом деле наше оборудование, власть и политика склоняются к стороне базы данных, поэтому все проходит через хранимую процедуру. К сожалению, они являются проблемой для программиста, особенно когда речь идет о метаданных и генерации кода, поскольку в хранимых процедурах не так много метаданных, как в таблицах.
Несмотря на это, вы все равно можете писать элегантный и чистый код, используя хранимые процедуры. В настоящее время я сам внедряю шаблон Repository со всеми хранимыми процедурами. Я бы посоветовал взглянуть на FluentAdo.net для его блестящей идеи при отображении из хранилища данных обратно в ваши бизнес-объекты. Я взял часть этой идеи и использовал ее для своего собственного решения.
источник
JFTR - я скромный PHP-разработчик, но это звучит как политический вопрос.
Учитывая масштабы «гниения», поддерживающего приложение, тогда, если не учитывать лучшие практики , будут существенные накладные расходы на его устранение. Похоже, это граничит с территорией переписать.
Можете ли вы гарантировать, что предложенная вами альтернатива принесет пользу для оправдания затрат для бизнеса? Я подозреваю, что рентабельность инвестиций этого предприятия может быть трудно продать бизнесу. Если приложение не является нестабильным, или вы можете доказать ценность капитального ремонта в финансовом плане - это может оказаться затруднительным.
Является ли ORM единственной альтернативой SPROCS? Существует несколько шаблонов проектирования между полноценным ORM и ванильным SQL. Возможно, вы могли бы начать процесс, постепенно выводя эти SPROCS из DB в DBAL. Конечно, существует опасность, что со временем это превратится в доморощенный ОРМ, но вы бы приблизились к цели.
источник
Мы перешли с SP на ORM несколько лет назад.
В одном случае нам пришлось обновить 80 таблиц. Старая модель оценки оценивала бы это в 80 часов с помощью entlib и SP. Мы сделали это в 10 :)
Это позволило нам сократить время, затрачиваемое на разработку уровня доступа к данным, на 80%.
источник
Мне кажется, что основной причиной является то, что ваши развертывания не работают должным образом и автоматически.
Может быть проще настроить механизм непрерывной сборки, который знает, как манипулировать базами данных при необходимости после каждой фиксации.
источник