Миграции с EF. Где они хранятся?

#entity-framework-4 #migration

#entity-framework-4 #миграция

Вопрос:

Вчера я был абсолютно уверен, что все данные миграции для EF, размещенные в классах, помещены в мое решение как вложенные из DbMigration. Но сегодня я копнул немного глубже (просто попробуйте вернуться к старой миграции, включив потерю данных не с помощью nu-get и visual studio, а с помощью code ())

 DbMigrator fg = new DbMigrator(new Settings() { AutomaticDataLossEnabled = true});

fg.Update("MigrationName");
  

И получить исключение, что-то вроде «строка должна быть усечена», это означает, что мигратор пытался обновить столбец с большого атрибута MaxLength на маленький. Итак, я исключил миграцию, которая вызвала это обновление, и перенес эти изменения в миграцию, создав таблицы. Ошибка все еще произошла. Я добрался до intellitrace, и там было сказано, что эта (удаленная) миграция все еще вызывалась. Просмотр запросов сказал мне такие вещи:

 SELECT [Extent1].[MigrationId] AS [MigrationId] FROM [dbo].[__MigrationHistory] AS [Extent1]    
  

Просматриваю таблицу __MigrationsHistory и получаю там мою удаленную миграцию с полевой моделью, которая содержит зашифрованные данные (пока не расшифровывайте это). Я был действительно шокирован. Означает ли это, что весь код, написанный в классах, является просто поддельным и действительно выполняемым кодом, размещенным здесь? И кто-нибудь знает, как работать с этой таблицей, регистрировать в ней проекции классов миграции и т. Д. Или единственный способ работы с миграциями — это nu-get console?

Ответ №1:

Я не совсем уверен, в чем заключается ваш основной вопрос, поэтому сначала я попытаюсь ответить на последнюю часть о __MigrationHistory таблице.

Код в классах не поддельный, ваш код в классах скомпилирован и запущен.

Однако эта таблица действительно содержит вашу модель базы данных, но она не зашифрована, она сжата. Причина, по которой API миграции должен хранить вашу модель, заключается в том, чтобы иметь возможность сравнивать ее с вашей текущей фактической моделью и отслеживать изменения для вас (например, когда вы добавляете новое свойство, оно сможет определить, какое свойство вы добавили, и выполнить автоматическую миграцию БД).

В предыдущей версии EF была таблица EdmMetadata, в которой хранился хэш вашей модели, и EF смог определить, внесли ли вы какие-либо изменения в модель, сравнив сохраненное и текущее значение хэша модели. Новая версия, в которой включена миграция, сохраняет всю модель в виде сжатого большого двоичного объекта, поэтому она может различать модель, которая использовалась для создания базы данных, и текущую модель, которую вы используете, и соответственно выполнять автоматическую миграцию.

Вы не должны работать непосредственно с этой таблицей, она автоматически заполняется API миграции, но консоль nuget — не единственный способ выполнить миграцию, вы можете проверить этот ресурс, чтобы узнать, как это сделать из кода.

Теперь, что касается вашего вопроса из заголовка вопроса (где они хранятся?), Миграции хранятся в коде, в классе, наследуемом от DbMigration класса, который migrations API создает для вас, когда вы выполняете команду Add-Migration в консоли nuget. Когда вы выполняете миграцию (обновление базы данных) либо из консоли диспетчера пакетов nuget, либо из кода, API сравнит вашу текущую модель с версиями, __MigrationsHistory чтобы найти начальную версию (если вы ее не указали) и выполнить все миграции между начальной и целевой версиями (если не указано иное, целевая версия является последнейверсия).

Я не совсем понимаю, как вы исключили свою миграцию, которая вызывает проблемы, поскольку вам необходимо перенести вашу базу данных в версию до этой миграции, а затем удалить и воссоздать все последующие миграции оттуда.

Может быть, вы могли бы решить проблему возврата к старой версии, внедрив public override void Down() в свою миграцию метод, который вызывает проблемы при попытке отката? Этот метод можно использовать для выполнения кода, который выполняет обратные любые операции для миграции.

Не имеет прямого отношения к вопросу, но стоит упомянуть, что здесь также есть довольно подробное руководство по EF CF.

Комментарии:

1. Также имейте в виду при отладке подобной проблемы, что отпечаток схемы базы данных хранится в файле ресурсов, подключенном к файлу миграции. Отпечаток пальца копируется в __Таблицу миграции в базе данных. Если вы посмотрите на файл resx (resource) в Visual Studio, вы можете не увидеть двоичный файл; для этого откройте файл resx в виде текста. FWIW.