Я не могу комментировать другие ORM, но я использую DevExpress XPO для корпоративного казначейского приложения с 2007 года. Схема немного меняется с каждым выпуском, но также были и некоторые большие изменения схемы за эти годы. Несколько расширенная версия стандартного механизма обновления XPO комфортно учла все изменения.
здесь есть полезная основная информация об обновлении приложений XPO.
DevExpress предоставляет инструмент DBUpdater, который поможет вам в обновлении производственных сред. Вы можете расширить этот инструмент для удовлетворения дополнительных требований. В моем приложении мы добавили несколько параметров для ведения журнала, предварительного просмотра с откатом и т. Д.
У каждого модуля есть виртуальные UpdateDatabaseBeforeSchemaUpdate()
и UpdateDatabaseAfterSchemaUpdate()
методы. В них вы можете значительно контролировать процесс обновления.
Как вы упомянули, некоторые обновления будут выполняться автоматически XPO (например, добавление нового столбца), но для некоторых вещей требуется дополнительный контроль, например, инициализация нового столбца со значением по умолчанию для существующих записей.
Например, предположим, что MyNewField
был добавлен в класс MyEntity
XPO в версии 2.0 вашего приложения. Допустим, для существующих записей по умолчанию должно быть установлено значение 3. XPO обработает создание нового столбца, но существующие записи будут 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>()
и foreach
, если предпочитаете избегать прямого SQL.)
В вашем более крайнем примере разделения таблицы на две вы можете использовать тот же метод, но вместо этого вы должны переопределить UpdateDatabaseBeforeUpdateSchema()
, запустить SQL для разделения таблицы, позволить XPO выполнить любые другие обновления схемы и, при необходимости, заполнить любые значения по умолчанию. в UpdateDatabaseAfterUpdateSchema()
.
Вы обнаружите, что столкнетесь с проблемами ограничений, например, нарушениями внешнего ключа, поэтому вам может потребоваться написать некоторые общие процедуры, такие как DropAllForeignKeyConstraints()
, как часть UpdateDatabaseBeforeUpdateSchema()
. Иногда вы обнаруживаете, что XPO уже что-то предоставляет, иногда нет. Отсутствующие ограничения и индексы будут восстановлены при обновлении схемы. (По моему опыту, переключение первичного ключа таблицы основных данных оказалось самой сложной процедурой обновления, которую нужно выполнить.)
По умолчанию все вызовы происходят в транзакции SQL, поэтому в случае сбоя все должно откатиться.
Разработчики должны знать, когда изменение модели предметной области может вызвать проблемы с базовой схемой.
Для тестирования мы храним несколько старых клиентских баз данных и запускаем несколько тестов до и после в рамках процесса сборки, чтобы убедиться, что существующие клиенты могут правильно обновить любую версию, с которой они обновляются. В производственной среде всякий раз, когда мы сталкиваемся с проблемой при обновлении, данные о проблеме добавляются в эту тестовую библиотеку, чтобы предотвратить подобные проблемы в будущем.
Мы работаем с крупными международными компаниями и банками. Результатом остались довольны покупатели. В ситуациях, когда корпоративному администратору баз данных необходимо подписывать изменения, они, кажется, не возражают против использования инструмента командной строки для выполнения обновления, а не сценария.
15.06.2012