DevExpress XPO vs NHibernate vs Entity Framework: проблема обновления базы данных
какова наилучшая практика обновления базы данных с помощью ОРМ (DevExpress XPO, NHibernate или MS Entity Framework)?
Я начинаю новый проект и выберите ОРМ. Процесс разработки требует выпуска промежуточных тестовых сборок довольно часто и, вероятно, каждая сборка будет иметь изменения в структуре базы данных. Каждая новая версия должна обновить DB мягко, чтобы сохранить ток данные.
для старых решений я бы предоставил набор сценариев SQL для обновления базы данных с v1 to v2 С v2 to v3, etc. и выполняйте их последовательно.
но как это будет работать для ОРМ? Должен ли я по-прежнему писать сценарии SQL для обновления БД?
Я понимаю, что простое добавление новых полей не вызывает проблем (например, см. UpdateSchema() метод для XPO), но что, если мне придется разделить таблицу и перераспределить текущие записи в 2 новые таблицы?
4 ответов
я не могу комментировать другие ORM, но я использовал DevExpress XPO для корпоративного казначейства с 2007 года. Схема немного меняется с каждым выпуском, но также были некоторые большие изменения схемы на протяжении многих лет. Несколько расширенная версия механизма обновления XPO по умолчанию удобно обслуживала все изменения.
есть хорошая основная информация здесь об обновлении XPO приложения.
DevExpress предоставляет инструмент DBUpdater, чтобы помочь вам с задачей обновления производственных сред. Вы можете расширить этот инструмент, чтобы удовлетворить дополнительные требования. В моем приложении мы добавили некоторые опции для ведения журнала, предварительного просмотра с откатом и т. д.
каждый модуль имеет виртуальный
UpdateDatabaseBeforeSchemaUpdate()
иUpdateDatabaseAfterSchemaUpdate()
методы. Вы можете значительно контролировать процесс обновления внутри эти.
как вы упомянули, некоторые обновления будут обрабатываться автоматически XPO (например, добавление нового столбца), но некоторые вещи нуждаются в дополнительном контроле, таком как инициализация нового столбца со значением по умолчанию для существующих записей.
например, скажем MyNewField
добавлено MyEntity
класс XPO в версии 2.0 вашего приложения. Допустим, по умолчанию для существующих записей должно быть значение 3. Центр будет заниматься созданием новый столбец, но существующие записи будут иметь значение NULL. (Если вы укажете значение по умолчанию в классе XPO, оно будет относиться только к новым записям). Чтобы исправить значение для существующих записей, вы должны добавить что-то вроде следующего к переопределенному модулю сущности UpdateDatabaseAfterSchemaUpdate()
:
public override void UpdateDatabaseAfterUpdateSchema()
{
base.UpdateDatabaseAfterUpdateSchema();
if (CurrentDBVersion < new Version(2, 0, 0, 0))
ObjectSpace.GetSession().ExecuteNonQuery(
"UPDATE [MyEntity] SET [MyNewField] = 3 WHERE [MyNewField] IS NULL");
}
(вы также можете использовать ObjectSpace.GetObjects<MyEntity>()
и a foreach
если вы предпочитаете избегать прямого SQL.)
в более экстремальный пример разбиения таблицы на две части, вы можете использовать тот же метод, но вы будет переопределять UpdateDatabaseBeforeUpdateSchema()
вместо этого запустите SQL для разделения таблицы, пусть XPO выполняет любые другие обновления схемы и, при необходимости, заполняет любые значения по умолчанию в UpdateDatabaseAfterUpdateSchema()
.
вы обнаружите, что сталкиваетесь с проблемами ограничений, например, нарушениями внешнего ключа, поэтому вам может потребоваться написать некоторые общие процедуры, такие как DropAllForeignKeyConstraints()
в рамках UpdateDatabaseBeforeUpdateSchema()
. Иногда вы обнаруживаете, что XPO уже что-то предоставляет, иногда нет. Отсутствующие ограничения и индексы будут восстановлены в обновлении схемы. (По моему опыту, переключение первичного ключа таблицы основных данных оказалось самой сложной процедурой обновления, чтобы получить право.)
по умолчанию все вызовы происходят в транзакции SQL, поэтому, если что-то не удается, все должно откатиться.
разработчикам необходимо знать, когда изменение модели домена может вызвать проблему с базовой схемой.
для тестирования мы храним несколько старых баз данных клиентов и запускаем кучу до и после тестов как часть процесса сборки, чтобы убедиться, что существующие клиенты могут правильно обновить любую версию, из которой они обновляются. В процессе производства, когда мы сталкиваемся с проблемой обновления, проблемные данные добавляются в эту тестовую библиотеку, чтобы предотвратить подобные проблемы в будущем.
мы имеем дело с крупными международными компаниями и банками. Клиенты вполне довольны результатом. В ситуациях, когда DBA корпорации необходимо подписать изменения, они, похоже, не возражают иметь инструмент командной строки для обновления, а не сценарий.
большинство решений миграции могут обрабатывать простые задачи, такие как добавление нового столбца, связь или удаление, но не работают при переименовании столбца (это добавление? или удалить после добавления, которое равно переименованию? Что делать с данными в этом случае?)
все три решения имеют базовую поддержку миграции, XPO даже позволяет запускать собственные скрипты как часть процесса (для вставки статических/тестовых / контантных данных и т. д.)
там же MigratorDotNet проект, который вы можете использовать и не полагаться на какую-либо конкретную функцию ORM в отношении миграции.
лично я бы использовал автоматическую миграцию только в среде разработки / тестирования и имел бы полный набор сценариев обновления при запуске на клиентской базе данных, чтобы сказать обновление с v1 до v2.
Как это будет работать для ORM? Должен ли я по-прежнему писать сценарии SQL для обновить БД?
четкий ответ на этот вопрос должен быть в потоке StackExchange программиста -каковы критерии оценки ОРМ for.NET?, там я получил простой ответ на ваш вопрос, который вы задали, и соответствует моему опыту работы с ORM при разработке некоторого проекта с Entity framework и Code smith ORM шаблоны.
как ORM управляет изменениями в модели данных? что делать, если мне нужно разделить таблицу и перераспределить текущие записи в 2 новые таблицы?
некоторые могут автоматически обновлять БД в пределах определенной меры, другие не делай ничего, и вам придется делать грязную работу самостоятельно; другие предоставьте платформу для обработки изменений, которая позволяет управлять базой данных новинки. это означает, что каждая пара дни кто-то должен потратить час обновления модели, чтобы добавить таблицу или изменить типы данных, которые меняются
Ref:
https://softwareengineering.stackexchange.com/questions/6543/what-are-the-benefits-of-using-database-abstraction-by-orm
https://softwareengineering.stackexchange.com/questions/41739/best-arguments-for-against-introducing-orm-technology-into-a-companies-dev-proce/41833#41833
Если вы спросите - какова наилучшая практика обновления БД с помощью ORM-мой ответ: Не используйте его, если ваше приложение больше, чем приложение для любителей.
существует множество сценариев, в которых многие ORM не могут обеспечить поддержку ваших конкретных потребностей базы данных, например, при создании хранимых процедур, создании индексов и представлений или даже индексированных представлений/материализованных таблиц без написания сценариев sql. Такие проблемы, как добавление нового столбца с ненулевым значением в существующую таблицу, намного сложнее решать в ORM-Migration-коде, чем путем написания SQL скриптов.
текущие инструменты, такие как Visual Studio Data Tools, лучше справляются с такими проблемами.