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?
  • Entity Framework / SQL2008 - Как автоматически обновлять поля LastModified для объектов?
  • Какие эффекты могут иметь ключевое слово virtual в Entity Framework 4.1 POCO Code First?
  • Возможно ли по умолчанию использовать поле DateTime для GETDATE () с миграциями Entity Framework?
  • Исключить поле / свойство из базы данных с Entity Framework 4 и Code-First
  • Entity Framework 4 выборочно ленивые свойства загрузки
  • Безопасность платформы Entity Framework
  • Отображение типа CLR типа EDM неоднозначно с EF 6 и 5?
  • Entity Framework 4 / POCO - С чего начать?
  • Результат запроса нельзя перечислить более одного раза
  • Указанное именованное соединение либо не находится в конфигурации, не предназначено для использования с поставщиком EntityClient, либо недействительно
  • Interesting Posts

    Неплохая ли практика комментировать одиночные строки CSS с помощью //?

    Ранняя и поздняя привязка

    Бесплатное программное обеспечение для конвертирования видео для Mac?

    connect ECONNREFUSED – узел js, sql

    Зарегистрируйтесь как элемент входа с cocoa?

    Как получить атрибуты стиля программно из styles.xml

    Поиск строки Java, игнорирующий акценты

    Как хранить очень большие цифры?

    Получение данных с кодировкой UTF-8 с сервера MSSQL с использованием расширения PHP FreeTDS

    постоянные ссылки с typedef и шаблонами в c ++

    Как объединить значения из нескольких строк в одну строку в Excel?

    Как включить «Momentum» (ака «Инерция») на ноутбуке с сенсорной панелью Elan?

    Есть ли инструменты для выравнивания динамических дисков в Windows 7?

    Действительно ли ifelse действительно вычисляет оба своих вектора каждый раз? Это медленно?

    Могу ли я заставить Thunderbird загружать разные учетные записи электронной почты один за другим, а не все одновременно?

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