4

У меня есть класс что-то вродемиграции Сформирован что уже Спички схемы

public class Foo 
{ 
    public virtual string Bar { get; set; } 
    // Other Stuff 
} 

Теперь надо лечить Bar как CHAR (8), поэтому я изменил свойство

[StringLength(8)] 
    [Column(TypeName = "char")] 
    public virtual string Bar { get; set; } 

Есть многие миграции в проекте, как правило, добавляют новые классы или новые свойства к существующим классам. Я знаю, что могу просто создать новую миграцию, которая изменит тип столбца, но, казалось, было немного запутанным, чтобы сначала создать столбец как NVARCHAR (Max), а затем изменить его на CHAR (8). Я редактировал первоначальные миграции, изменение

CreateTable(
    "dbo.Foo", 
    c => new 
     { 
      Bar = c.String(), 
      // Other stuff 
     }) 

в

CreateTable(
    "dbo.Foo", 
    c => new 
     { 
      Bar = c.String(maxLength: 8, fixedLength: true, storeType: "char", unicode: false), 
      // Other stuff 
     }) 

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

Я установил точку останова в этой начальной миграции, а также в конце последней миграции. Как только начальная миграция завершается, таблица Foo создается в недавно созданной базе данных с ожидаемым типом столбца CHAR (8). После окончательная миграция завершается, и я пытаюсь использовать контекст, я получаю AutomaticMigrationsDisabledException.

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

public override void Up() 
{ 
    AlterColumn("dbo.Foo", "Bar", c => c.String(maxLength: 8, fixedLength: true, unicode: false)); 
} 

public override void Down() 
{ 
    AlterColumn("dbo.Foo", "Bar", c => c.String()); 
} 

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

Вопрос

Почему EF попытка выполнить эту, казалось бы, ненужные миграции, и я могу изменить тип столбца без первого создания NVARCHAR (Max), а затем изменить его в CHAR (8) в новом, отдельная миграция?

+0

Проблема в каждой миграции хранит модель, которую он использует для сравнения. Код Changeing() не влияет на сохраненные модели. Вы можете прокомментировать это изменение и выполнить обновление базы данных, чтобы синхронизировать его, или вы можете сделать гораздо более сложное изменение модели gzipped resx. http://stackoverflow.com/questions/15709849/can-i-get-decode-an-entityframework-model-from-a-specified-migration –

+0

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

+0

Он сохраняется в процессе миграции в вашем решении. Если вы развернете одну из своих миграций в VS, вы увидите a.resx, который содержит метаданные для модели кода, используемой для создания миграции (gzipped XML). Когда он применяется к новой базе данных, он сохраняется в столбце модели каждой записи. Так как ваши изменения никогда не попадали в эту застегнутую на молнию модель, EF думает, что она все еще нуждается в ней. –

ответ

2

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

Не рекомендуется менять эти модели, хотя это link показывает, как вы можете его осмотреть. Рекомендованное обходное решение - создать новую миграцию, чтобы модель была вставлена ​​в ее файл ресурсов. Используйте флаг -IgnoreChanges для создания пустой миграции только с обновлением модели. См. https://msdn.microsoft.com/en-us/data/dn579398.aspx?f=255&MSPPError=-2147217396#option1

Смежные вопросы