Як увімкнути міграцію EF для кількох контекстів для розділення баз даних?


122

Як увімкнути міграцію 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.


Відповіді:


126

2-й виклик Enable-Migrations провалюється, оскільки файл Configuration.cs вже існує. Якщо ви перейменовуєте цей клас і файл, ви зможете запустити цей 2-й увімкнено-міграційний процес, який створить інший Configuration.cs.

Потім вам потрібно буде вказати, яку конфігурацію ви хочете використовувати під час оновлення баз даних.

Update-Database -ConfigurationTypeName MyRenamedConfiguration

1
Що таке "MyRenamedConfiguration"?
Роберт Ноак

1
"MyRenamedConfiguration" - це лише текст власника місця як приклад. Ви могли перейменувати свій оригінальний Configuration.cs у будь-що (наприклад, FooBar, потім запустіть Update-Database -ConfigurationTypeName FooBar).
ckal

3
скоротити форму: Update-Database -conf MyRenamedConfiguration
Peter Kerr

100

На додаток до того, що @ckal запропонував, важливо надати кожному перейменованому Configuration.cs свій простір імен. Якщо цього не зробити, EF спробує застосувати міграцію до неправильного контексту.

Ось конкретні кроки, які добре працюють для мене.

Якщо міграція переплутана, і ви хочете створити нову "базову лінію":

  1. Видаліть усі існуючі файли .cs у папці Міграції
  2. У SSMS видаліть системну таблицю __MigrationHistory.

Створення початкової міграції:

  1. У консолі диспетчера пакунків:

    Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextA
  2. У Провіднику рішень: Перейменуйте Migrations.Configuration.cs на Migrations.ConfigurationA.cs. Це має автоматично перейменувати конструктор, якщо використовується Visual Studio. Переконайтесь, що це так. Редагування ConfigurationA.cs: Змініть простір імен на NamespaceOfContext.Migrations.MigrationsA

  3. Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB
  4. У Провіднику рішень: Перейменуйте Migrations.Configuration.cs на Migrations.ConfigurationB.cs. Знову ж таки, переконайтеся, що конструктор також був перейменований відповідним чином. Редагування ConfigurationB.cs: Змініть простір імен на NamespaceOfContext.Migrations.MigrationsB

  5. add-migration InitialBSchema -IgnoreChanges -ConfigurationTypeName
    ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB 
  6. Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB
  7. add-migration InitialSurveySchema -IgnoreChanges -ConfigurationTypeName
    ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName
    NameOfMainProject  -ConnectionStringName ContextA 
  8. Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

Кроки для створення сценаріїв міграції в консолі диспетчера пакунків:

  1. Виконати команду

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    або -

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

    Добре повторити цю команду, поки зміни не будуть застосовані до БД.

  2. Або запустіть скрипти на потрібній локальній базі даних або запустіть Update-Database без -Script, щоб застосувати локально:

    Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    або -

    Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

# 4 зміна: Редагувати ConfigurationA.cs -> Редагувати ConfigurationB.cs
Брайан Різо

1
@Biran: Дякую, що помітили це. Я відредагував відповідь. Зверніть увагу, ви також можете редагувати відповіді. Оскільки у вас ще немає 2000 репутації, ваші відповіді на чергу огляду, але цю чергу, як правило, працюють швидко, тому ваша редакція, ймовірно, буде затверджена протягом декількох хвилин.
Ерік Дж.

5
СПАСИБІ! Це мені не вистачало (простори імен).
Вільям М. Роулс

Це може допомогти, оскільки мені було незрозуміло, як зробити перейменування на етапах 2 та 4 спочатку: Коли ви перейменовуєте файл Configuration.cs у ConfigurationA.cs або ConfigurationB.cs, перейменування також повинно призвести до класу та його конструктор також перейменований на ConfigurationA або ConfigurationB. Якщо не перейменувати клас, це призведе до повідомлення про помилку при запуску команди add-migration - "Тип конфігурації міграцій" ConfigurationA "не було знайдено у складі" ... "" - і так, формулювання було поганим, як і що в повідомленнях про помилки, які я отримав у VS2013 - LOL
Грег Барт

3
це мені допомогло! повні інструкції з усіма параметрами та замовлення. врятувало мене години
elcool

81

Я просто наткнувся на ту ж проблему, і я застосував таке рішення (все з консолі менеджера пакунків)

PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextA" -ContextTypeName MyProject.Models.ContextA
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextB" -ContextTypeName MyProject.Models.ContextB

Це створить дві окремі папки в папці Міграції. Кожен буде містити створений Configuration.csфайл. На жаль, вам все одно доведеться перейменувати ці Configuration.csфайли, інакше з’являться скарги на наявність двох з них. Я перейменував свої файли в ConfigA.csтаConfigB.cs

EDIT : (люб’язно Кевін МакПіат) Пам'ятайте, перейменуючи файли Configuration.cs, також перейменуйте назви класів та конструктори / EDIT

З цією структурою можна просто обійтися

PM> Add-Migration -ConfigurationTypeName ConfigA
PM> Add-Migration -ConfigurationTypeName ConfigB

Який створить файли коду для міграції всередині папки поруч із конфігураційними файлами (це приємно зберігати ці файли разом)

PM> Update-Database -ConfigurationTypeName ConfigA
PM> Update-Database -ConfigurationTypeName ConfigB

І останнє, але не менш важливо, ці дві команди застосовують правильні міграції до своїх баз даних, що відповідають вимогам.

EDIT 08 лютого 2016: Я трохи провів тестування з версією 7.0.0-rc1-16348 EF7

Я не зміг отримати можливість -o | --outputDir працювати. Це продовжувало даватиMicrosoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

Однак це схоже на те, що перший раз, коли миграція додається, вона додається в папку Міграції, а наступна міграція для іншого контексту автоматично поміщається в підрозділ міграцій.

Оригінальні назви, 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цієї папки. Потім я перейменував простір імен всередині цих файлів (файл знімка, початкова міграція і зауважу, що під початковим файлом міграції є третій файл ... дизайнер.cs). Мені довелося додати .ContextAдо простору імен, і звідси фреймворк знову обробляє його.

Використання наступних команд створило б нову міграцію для кожного контексту

PM>  dnx ef migrations add Update1 -c "ContextAContext"
PM>  dnx ef migrations add Update1 -c "ContextBContext"

і створені файли поміщаються у правильні папки.


5
найкраще рішення, просте, і ми зберігаємо чітку папку.
Малик

2
Це була потрібна мені відповідь. Простір імен, доданий через -MigrationsDirectory, був відповіддю! Дякую.
Кроб

1
Приємне і чисте рішення. Дякую.
Стефан Чебулак

4
Через 1,5 року я щасливий, що можу використовувати свій власний пост, щоб створити новий проект.
барт

1
Зауважте, що при запуску add-migrationвін запропонує вам Name. Це трохи відкинуло мене, оскільки я вже надав ConfigurationTypeNameі трохи роздратований, коли це просто сказав Name:. Але, звичайно, ім'я, яке воно хоче, - це "читабельний для людини" опис зміни - наприклад. AddedProductsабо IncreaseLengthOfNameFields. У папці Міграції ви отримаєте це як частину назви класу, тому легко зрозуміти, що є. Таким чином, насправді Nameце як коментар до реєстрації.
Simon_Weaver

7

Якщо у вас вже є "Конфігурація" з багатьма міграціями, і ви хочете зберегти це так, як є, ви завжди можете створити новий клас "Конфігурація", дайте йому іншу назву, наприклад

class MyNewContextConfiguration : DbMigrationsConfiguration<MyNewDbContext>
{
   ...
}

тоді просто видайте команду

Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName

і EF допоможе без проблем перемістити міграцію. Нарешті оновіть вашу базу даних, відтепер EF буде скаржитися, якщо ви не скажете йому, яку конфігурацію ви хочете оновити:

Update-Database -ConfigurationTypeName MyNewContextConfiguration 

Зроблено.

Вам не потрібно мати справу з Enable-Migrations, оскільки він скаржиться на те, що "Конфігурація" вже існує, а перейменування існуючого класу Configuration призведе до проблем міграції.

Ви можете орієнтуватися на різні бази даних або одну і ту ж, всі конфігурації будуть добре розподіляти таблицю __MigrationHistory.


4

Якщо існує більше баз даних, використовуйте наступні коди в PowerShell

Add-Migration Starter -context EnrollmentAppContext 
  • "Стартер" - це назва міграції

  • "EnrollmentAppContext" - це ім'я мого додатка Контекст

Ви можете відкрити PowerShell в VS, виконавши: Tools->NuGet Package Manager->Package Manager Console


1
Це мені допомогло. Дякую! :)
noobprogrammer

3

Для оновлення типу бази даних наступні коди в PowerShell ...

Update-Database -context EnrollmentAppContext

* якщо існує більше ніж одна база даних, використовуйте лише ці коди, інакше не потрібно.


0

EF 4.7 насправді дає підказку під час запуску міграції Enable у різних контекстах.

У збірці "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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.