Почему моя миграция вызывает неправильный DbContext? [Дубликат]

Это инициализатор объекта Property Shorthand в ES6.

var f = {a, b, c, d:1}; // Will be equal to {a:a, b:b, c:c, d:1}

Это работает, потому что значение свойства имеет то же имя, что и идентификатор свойства. Это новое дополнение к синтаксису Object Initialiser ( section 11.1.5 ) в последнем проекте ECMAScript 6 Draft Rev 13 . И, конечно же, как и ограничения, установленные в ECMAScript 3, вы не можете использовать зарезервированное слово в качестве вашего имени свойства.

Такая стенография не приведет к резкому изменению вашего кода, это лишь делает все немного бит слаще!

function createCar(name, brand, speed) {
  return { type: 'Car', name: name, brand: brand, speed: speed };
}

// With the new shorthand form
function createSweetCar(name, brand, speed) {
  return { type: 'Car', name, brand, speed }; // Yes it looks sweet.
}

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

Эта сокращенная нотация предлагает довольно точное сопоставление объектов:

В ECMAScript5 мы использовали:

var tmp = getDate();
var op  = tmp.op;
var lhs = tmp.lhs;
var rhs = tmp.rhs;

Может быть сделано в ECMAScript6 с одной строкой кода:

var { op, lhs, rhs } = getData();

21
задан Joachim Rosskopf 2 February 2012 в 14:01
поделиться

9 ответов

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

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

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

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

6
ответ дан bricelam 25 August 2018 в 21:08
поделиться

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

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

1
ответ дан Alan Macdonald 25 August 2018 в 21:08
поделиться

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

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

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

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

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

Add-Migration -configuration Configuration1 Context1Init

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

Add-Migration -configuration Configuration2 Context2Init

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

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

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

32
ответ дан Anuj Pandey 25 August 2018 в 21:08
поделиться

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

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

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

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

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

3
ответ дан Chris Moschini 25 August 2018 в 21:08
поделиться

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

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

0
ответ дан mackie 25 August 2018 в 21:08
поделиться

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

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

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

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

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

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

internal sealed class Configuration1 : DbMigrationsConfiguration<Context1>{
       public Configuration1 (){
        AutomaticMigrationsEnabled = false;
   }
 }

internal sealed class Configuration2 : DbMigrationsConfiguration<Context2>{
   public Configuration2 (){
        AutomaticMigrationsEnabled = false;
   }
}

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

0
ответ дан Notso 25 August 2018 в 21:08
поделиться

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

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

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

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

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

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

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

Это, по моему мнению, главный недостаток.

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

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

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

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

1
ответ дан Rick Ellis 25 August 2018 в 21:08
поделиться

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

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

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

1
ответ дан user1718625 25 August 2018 в 21:08
поделиться

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

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

0
ответ дан Westy 25 August 2018 в 21:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: