Как включить EF-миграции для разных контекстов для разделения баз данных?
Как включить миграцию Entity Framework 5 (версия 5.0.0) для нескольких контекстов БД в том же проекте, где каждый контекст соответствует собственной базе данных? Когда я запускаю Enable-Migrations
в консоли PM (Visual Studio 2012), появляется ошибка из-за наличия нескольких контекстов:
PM> Enable-Migrations
More than one context type was found in the assembly 'DatabaseService'.
To enable migrations for DatabaseService.Models.Product1DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext.
To enable migrations for DatabaseService.Models.Product2DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext.
Если я запустил Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext
, мне не разрешено запускать Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext
, потому что миграция уже существует: Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.
Ответы
Ответ 1
Второй вызов Enable-Migrations не работает, потому что файл Configuration.cs уже существует. Если вы переименуете этот класс и файл, вы должны будете запустить эту вторую Enable-Migrations, которая создаст другую Configuration.cs.
Затем вам нужно указать, какую конфигурацию вы хотите использовать при обновлении баз данных.
Update-Database -ConfigurationTypeName MyRenamedConfiguration
Ответ 2
В дополнение к тому, что предложил @ckal, это критический, чтобы дать каждому переименованному Configuration.cs собственное пространство имен. Если вы этого не сделаете, EF попытается применить миграции к неправильному контексту.
Вот конкретные шаги, которые хорошо работают для меня.
Если Миграции перепутаны, и вы хотите создать новую "базовую линию":
- Удалите все существующие файлы .cs в папке Migrations
- В SSMS удалите системную таблицу __MigrationHistory.
Создание начальной миграции:
-
В консоли диспетчера пакетов:
Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
-StartupProjectName NameOfMainProject -ConnectionStringName ContextA
-
В обозревателе решений: переименуйте Migrations.Configuration.cs в Migrations.ConfigurationA.cs. Это должно автоматически переименовывать конструктор при использовании Visual Studio. Убедитесь, что это так.
Изменить ConfigurationA.cs: изменить пространство имен на NamespaceOfContext.Migrations.MigrationsA
-
Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne
-StartupProjectName NameOfMainProject -ConnectionStringName ContextB
-
В обозревателе решений: переименуйте Migrations.Configuration.cs в Migrations.ConfigurationB.cs. Опять же, убедитесь, что конструктор также переименован соответствующим образом.
Изменить ConfigurationB.cs: изменить пространство имен на NamespaceOfContext.Migrations.MigrationsB
-
add-migration InitialBSchema -IgnoreChanges -ConfigurationTypeName
ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne
-StartupProjectName NameOfMainProject -ConnectionStringName ContextB
-
Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
-ConnectionStringName ContextB
-
add-migration InitialSurveySchema -IgnoreChanges -ConfigurationTypeName
ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName
NameOfMainProject -ConnectionStringName ContextA
-
Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
-ConnectionStringName ContextA
Шаги по созданию сценариев миграции в консоли диспетчера пакетов:
-
Запустить команду
Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationA -ProjectName
ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
-ConnectionStringName ContextA
или -
Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationB -ProjectName
ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
-ConnectionStringName ContextB
ОК, чтобы повторно запустить эту команду, пока в базу данных не будут внесены изменения.
-
Либо запускайте скрипты с нужной локальной базой данных, либо запустите Update-Database без - Script, чтобы применить локально:
Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
-ConnectionStringName ContextA
или -
Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
-ConnectionStringName ContextB
Ответ 3
Я просто столкнулся с той же проблемой, и я использовал следующее решение (все из консоли диспетчера пакетов)
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextA" -ContextTypeName MyProject.Models.ContextA
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextB" -ContextTypeName MyProject.Models.ContextB
Это создаст две отдельные папки в папке Migrations. Каждый из них будет содержать сгенерированный файл Configuration.cs
. К сожалению, вам все равно придется переименовывать те файлы Configuration.cs
, иначе будут жалобы на наличие двух из них. Я переименовал свои файлы в ConfigA.cs
и ConfigB.cs
РЕДАКТИРОВАТЬ: (вежливость Кевин МакФит) Помните при переименовании файлов Configuration.cs, также переименуйте имена классов и конструкторы /EDIT
С помощью этой структуры вы можете просто сделать
PM> Add-Migration -ConfigurationTypeName ConfigA
PM> Add-Migration -ConfigurationTypeName ConfigB
Что создаст файлы кода для миграции внутри папки рядом с конфигурационными файлами (это хорошо, чтобы сохранить эти файлы вместе)
PM> Update-Database -ConfigurationTypeName ConfigA
PM> Update-Database -ConfigurationTypeName ConfigB
И последнее, но не менее важное: эти две команды будут применять правильные миграции для своих корневых баз данных.
РЕДАКТИРОВАТЬ 08 февраля 2016 года:
Я провел небольшое тестирование с EF7 версии 7.0.0-rc1-16348
Я не мог использовать параметр -o | --outputDir. Он продолжал давать Microsoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument
Однако похоже, что при первом добавлении переноса он добавляется в папку Migrations, а последующая миграция для другого контекста автоматически помещается в поддокладчик миграции.
Оригинальные имена ContextA
, похоже, нарушают некоторые соглашения об именах, поэтому теперь я использую ContextAContext
и ContextBContext
. Используя эти имена, вы можете использовать следующие команды:
(обратите внимание, что мой dnx по-прежнему работает из консоли диспетчера пакетов, и я не люблю открывать отдельное окно CMD для миграции).
PM> dnx ef migrations add Initial -c "ContextAContext"
PM> dnx ef migrations add Initial -c "ContextBContext"
Это создаст моментальный снимок модели и начальную миграцию в папке Migrations
для ContextAContext
. Он создаст папку с именем ContextB
, содержащую эти файлы для ContextBContext
Я вручную добавил папку ContextA
и переместил файлы миграции из ContextAContext
в эту папку. Затем я переименовал пространство имен внутри этих файлов (моментальный снимок, начальную миграцию и заметьте, что есть третий файл в файле начальной миграции... designer.cs). Мне пришлось добавить .ContextA
в пространство имен, и оттуда фреймворк обработает его автоматически снова.
Использование следующих команд создаст новую миграцию для каждого контекста
PM> dnx ef migrations add Update1 -c "ContextAContext"
PM> dnx ef migrations add Update1 -c "ContextBContext"
и сгенерированные файлы помещаются в правильные папки.
Ответ 4
Если у вас уже есть "Конфигурация" со многими миграциями и вы хотите сохранить это как есть, вы всегда можете создать новый класс "Конфигурация" , дать ему другое имя, например
class MyNewContextConfiguration : DbMigrationsConfiguration<MyNewDbContext>
{
...
}
то просто введите команду
Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName
и EF без проблем справится с миграцией. Наконец, обновите свою базу данных, с этого момента EF будет жаловаться, если вы не скажете ему, какую конфигурацию вы хотите обновить:
Update-Database -ConfigurationTypeName MyNewContextConfiguration
Готово.
Вам не нужно иметь дело с Enable-Migrations, поскольку он будет жаловаться "Конфигурация" уже существует, и переименование существующего класса конфигурации приведет к проблемам в истории миграции.
Вы можете настроить таргетинг на разные базы данных или на одну и ту же, все конфигурации будут хорошо делиться таблицей __MigrationHistory.
Ответ 5
Если существует больше баз данных, используйте следующие коды в PowerShell
Add-Migration Starter -context EnrollmentAppContext
Вы можете открыть PowerShell в VS, выполнив:
Tools->NuGet Package Manager->Package Manager Console
Ответ 6
Чтобы обновить базу данных, введите следующие коды в PowerShell...
Update-Database -context EnrollmentAppContext
* если существует более одной базы данных, используйте только эти коды, в противном случае нет необходимости..
Ответ 7
EF 4.7 фактически дает подсказку, когда вы запускаете Enable-migrations в нескольких контекстах.
В сборке "Service.Domain" обнаружено несколько типов контекста.
To enable migrations for 'Service.Domain.DatabaseContext.Context1',
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context1.
To enable migrations for 'Service.Domain.DatabaseContext.Context2',
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context2.