EF 4.3 Автоматическая миграция с несколькими DbContexts в одной базе данных

Я пытаюсь использовать EF 4.3 миграции с несколькими кодовыми DbContexts. Мое приложение разделено на несколько плагинов, которые, возможно, имеют свой собственный DbContext в отношении своего домена. Приложение должно использовать одну единственную базу данных sql.

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

Поэтому мой вопрос:

  • Как передать конфигурацию миграции только для того, чтобы следить за таблицами, определенными в их соответствующем контексте, и оставить всех остальных в покое?
  • Каков правильный рабочий процесс для работы с несколькими DbContexts с автоматической миграцией в одной базе данных?

Спасибо!

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

Я могу представить два возможных решения:

  1. Создайте совокупный контекст, который включает все сущности каждого контекста и ссылается на этот «супер» контекст из вашего classа конфигурации миграции. Таким образом, все таблицы будут созданы в базе данных пользователя, но данные будут только в тех, к которым они устанавливали плагины.

  2. Используйте отдельные базы данных для каждого контекста. Если у вас есть общие объекты между контекстами, добавьте настраиваемую миграцию и замените CreateTable(...) вызовом Sql("CREATE VIEW ...") чтобы получить данные из «исходной» базы данных сущности.

Я бы попробовал # 1, так как он хранит все в одной базе данных. Вы можете создать отдельный проект в своем решении, чтобы содержать ваши миграции и этот «супер» контекст. Просто добавьте проект, сориентируйте все проекты ваших плагинов, создайте контекст, который включает все объекты, а затем вызовите Enable-Migrations в этом новом проекте. После этого все должно работать так, как ожидалось.

Вот что вы можете сделать. очень просто.

Вы можете создать class конфигурации для каждого из ваших контекстов. например

 internal sealed class Configuration1 : DbMigrationsConfiguration{ public Configuration1 (){ AutomaticMigrationsEnabled = false; MigrationsNamespace = "YourProject.Models.ContextNamespace1"; } } internal sealed class Configuration2 : DbMigrationsConfiguration{ public Configuration2 (){ AutomaticMigrationsEnabled = false; MigrationsNamespace = "YourProject.Models.ContextNamespace2"; } } 

Теперь вы добавляете миграцию. Вам не нужно активировать миграцию, так как вы уже сделали это с classом 2, описанным выше.

 Add-Migration -configuration Configuration1 Context1Init 

Это создаст сценарий миграции для context1. вы можете повторить это снова для других Контекстов.

 Add-Migration -configuration Configuration2 Context2Init 

Чтобы обновить базу данных

 Update-Database -configuration Configuration1 Update-Database -configuration Configuration2 

Это можно сделать в любом порядке. Кроме того, вы должны убедиться, что каждая конфигурация вызывается последовательно.

У меня есть рабочий сайт с несколькими контекстами с использованием миграции. Однако вам нужно использовать отдельную базу данных для каждого контекста, и все это отключено от classа * Configuration в пространстве имен Migrations вашего проекта, поэтому, например, CompanyDbContext указывает на Company.sdf, используя CompanyConfiguration. update-database -configurationtypename CompanyConfiguration . Другой LogDbContext указывает на Log.sdf с использованием LogConfiguration и т. Д.

Учитывая это, попробовали ли вы создать 2 контекста, указывающих на одну и ту же базу данных, и сообщить разработчику модели игнорировать список таблиц другого контекста?

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Ignore(); // more of these } 

Поскольку миграции работают с ModelBuilder, это может сделать работу.

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

Хорошо, я боролся с этим в течение дня, и вот решение для тех, кто ищет ответ …

Я предполагаю, что большинство людей, читающих этот пост, здесь, потому что у них большой class DbContext с большим количеством свойств DbSet <>, и загрузка занимает много времени. Вы, наверное, подумали о себе, да, это имеет смысл, я должен разделить контекст, так как я не буду использовать все dbsets сразу, и я загружу только «частичный» контекст, основанный на ситуации, в которой мне нужно Это. Таким образом, вы разделили их, только чтобы узнать, что миграция Code First не поддерживает ваш путь революционного мышления.

Таким образом, ваш первый шаг должен был разделить контексты, а затем вы добавили class MigrationConfiguration для каждого из новых контекстов, вы добавили строки соединений, названные так же, как и ваши новые classы контекста.

Затем вы попытались запустить вновь разделенные контексты один за другим, выполнив Add-Migration Context1, а затем обновив-Database -Verbose …

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

Это связано с тем, что текущая модель Migrations ожидает Single DbContext для базы данных, и она должна быть зеркальным совпадением.

То, что я также пробовал, и кто-то предложил здесь сделать это, создает один SuperContext, в котором есть все Db. Создайте один class конфигурации миграции и запустите его. Оставьте свои частичные classы контекста на месте и попробуйте создать и использовать их. EF жалуется, что модель Backing изменилась. Опять же, это связано с тем, что EF сравнивает ваш частичный dbcontext с сигнатурой контекста All-Sets, оставшейся от миграции Super Context.

На мой взгляд, это главный недостаток.

В моем случае я решил, что PERFORMANCE важнее миграции. Итак, что я закончил делать, это после того, как я побежал в контексте Super и имел все таблицы на месте, я зашел в базу данных и вручную удалил таблицу _MigrationHistory.

Теперь я могу создавать и использовать свои частичные контексты без EF, жалующихся на это. Он не находит таблицу MigrationHistory и просто перемещается, что позволяет мне иметь «частичный» вид базы данных.

Конечно, компромисс заключается в том, что любые изменения в модели придется вручную распространять в базу данных, поэтому будьте осторожны.

Это сработало для меня.

Как упоминалось выше Брайсом, наиболее практичным решением является наличие 1 супер DbContext для каждого приложения / базы данных.

Необходимость использовать только 1 DbContext для целого приложения, по-видимому, является критическим техническим и методологическим недостатком, поскольку это влияет на модульность, среди прочего. Кроме того, если вы используете службы данных WCF, вы можете использовать только 1 DataService для каждого приложения, поскольку DataService может отображать только 1 DbContext. Таким образом, это значительно изменяет архитектуру.

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

Я просто столкнулся с этой проблемой и понял, что я разделил их на разные контексты, состоял в том, чтобы группировать связанные модели в управляемые куски, а не по какой-либо другой технической причине. Вместо этого я объявил свой контекст как частичный class, и теперь разные файлы кода с разными моделями в них могут добавлять DbSets в DbContext.

Таким образом, магия автоматизации все еще работает.

У меня есть работа с ручными миграциями, но вы не можете понизить ее, поскольку она не может различать конфигурации в таблице __MigrationHistory. Если я попытаюсь и понижаю рейтинг, он обрабатывает миграции из других конфигураций как автоматические, и, поскольку я не допускаю потери данных, это терпит неудачу. Мы будем использовать его только для обновления, поэтому он работает для наших целей.

Это похоже на довольно много, но я уверен, что было бы трудно поддержать его, если бы не было дублирования между DbContexts.

Разумеется, решение должно быть изменено командой EntityFramework для изменения API для поддержки прямой модификации таблицы _MigrationHistory на имя таблицы по вашему выбору, например _MigrationHistory_Context1, так что оно может обрабатывать модификацию независимых объектов DbContext. Таким образом, все они рассматриваются отдельно, а его разработчик должен гарантировать, что имена объектов не сталкиваются.

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

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

 internal sealed class Configuration1 : DbMigrationsConfiguration{ public Configuration1 (){ AutomaticMigrationsEnabled = false; MigrationsNamespace = "YourProject.Models.ContextNamespace1"; } } internal sealed class Configuration2 : DbMigrationsConfiguration{ public Configuration2 (){ AutomaticMigrationsEnabled = false; MigrationsNamespace = "YourProject.Models.ContextNamespace2"; } } 

Тем не менее, у меня уже было создано 2 базы данных с их собственными контекстами, поэтому я обнаружил ошибку: «Пространство имен YourProject.Models уже содержит ContextNamespace1». Это произошло потому, что «MigrationsNamespace =« YourProject.Models.ContextNamespace2 »;» вызывал dbcontext для определения в пространстве имен YourProjects.Models дважды после того, как я попробовал Init (один раз в файле Context1Init миграции и один раз, когда я определил его ранее).

Итак, я обнаружил, что то, что я должен был сделать в этот момент, – это запустить мою базу данных и миграции с нуля (к счастью, у меня не было данных, которые мне нужно было сохранить), следуя указаниям здесь: http://pawel.sawicz.eu/entity -framework-переустановка-миграция /

Затем я изменил код, чтобы НЕ включать строку MigrationsNamespace.

 internal sealed class Configuration1 : DbMigrationsConfiguration{ public Configuration1 (){ AutomaticMigrationsEnabled = false; } } internal sealed class Configuration2 : DbMigrationsConfiguration{ public Configuration2 (){ AutomaticMigrationsEnabled = false; } } 

Затем я снова выполнил команду Add-Migration -configuration Configuration1 Context1Init и строку Configuration-Configuration-ConfigurationFlash Configuration1 (для моего второго контекста), и, наконец, теперь все работает отлично.

  • Код элемента Entity Framework Первый метод AddOrUpdate insert Дублирующие значения
  • Entity Framework 4 / POCO - С чего начать?
  • Использование MySql с Entity Framework 4 и Code-First Development CTP
  • Entity Framework 4 Удалить объект из коллекции объектов
  • Как установить значение по умолчанию для POCO в EF CF?
  • Entity Framework Code First Fluent Api: добавление индексов в столбцы
  • Исключить поле / свойство из базы данных с Entity Framework 4 и Code-First
  • Представление ограничения FOREIGN KEY может вызвать циклы или несколько каскадных путей - почему?
  • Entity Framework 4 - AddObject vs Attach
  • Ошибка API-интерфейса Asp.Net: тип «ObjectContent`1» не смог сериализовать тело ответа для типа контента «application / xml»; кодировка = UTF-8'
  • LEFT JOIN в LINQ для объектов?
  • Interesting Posts

    getlastknownlocation всегда возвращает null после того, как я переустановил файл apk через eclipse

    Каков наилучший способ объявить глобальную переменную в Angular 2 / Typcript

    Как анализировать уличный / почтовый адрес свободной формы из текста и в компоненты

    Транспонирование кадра данных

    WCF, тип возврата интерфейса и известные типы

    Загрузка частичного представления в jquery.dialog

    Лучший (желательно бесплатный) инструмент для удаления удаленных файлов в файловой системе NTFS

    Лучший подход для синтаксического анализа XML на iPhone

    Работает ли C # 6.0 на .NET 4.0?

    Как присоединиться / объединить 2 таблицы рабочих таблиц с помощью 3-й таблицы в Excel?

    Что такое Apache Camel?

    Перенаправление аудио / создание альтернативных звуковых дорожек в Android

    Замок Виндзорский резольвер для MVC 3

    Постоянный куки для Android HttpClient

    Как найти количество строк для всех ваших таблиц в Postgres

    Давайте будем гением компьютера.