Подтвердить что ты не робот

EF5 Code First - Изменение типа столбца с миграцией

Я новичок в EF5 Code First, и я возился с концепцией концепции, прежде чем приступать к работе над проектом.

Я изначально создал модель, которая выглядела примерно как

public class Person {
  public int Id { get; set; }
  public string FirstName { get; set;}
  public string Surname {get;set;}
  public string Location {get;set;}
}

И я добавил несколько записей, используя небольшое приложение MVC, которое я застрял на вершине.

Теперь я хочу изменить столбец Location на перечисление, что-то вроде:

public class Person {
  public int Id { get; set; }
  public string FirstName { get; set;}
  public string Surname {get;set;}
  public Locations Location {get;set;}
}

public enum Locations {
  London = 1,
  Edinburgh = 2,
  Cardiff = 3
}

Когда я добавляю новую миграцию, я получаю:

AlterColumn("dbo.People", "Location", c => c.Int(nullable: false));

но когда я запускаю базу данных обновлений, я получаю сообщение об ошибке

Conversion failed when converting the nvarchar value 'London' to data type int.

Есть ли способ миграции, чтобы обрезать таблицу до запуска инструкции alter?

Я знаю, что могу открыть базу данных и вручную сделать это, но есть ли более разумный способ?

4b9b3361

Ответ 1

Самый умный способ, вероятно, не изменять типы. Если вам нужно это сделать, я предлагаю вам выполнить следующие действия:

  • Добавить новый столбец с новым типом
  • Используйте Sql(), чтобы перенести данные из исходного столбца с помощью оператора обновления
  • Удалить старый столбец
  • Переименовать новый столбец

Все это может быть выполнено при одной и той же миграции, будет создан правильный SQL script. Вы можете пропустить шаг 2, если хотите, чтобы ваши данные были отброшены. Если вы хотите взять это, добавьте соответствующий оператор (также может содержать оператор switch).

К сожалению, первые шаги миграции кода не обеспечивают более простые способы для этого.

Вот пример кода:

AddColumn("dbo.People", "LocationTmp", c => c.Int(nullable: false));
Sql(@"
    UPDATE dbp.People
    SET LocationTmp =
        CASE Location
            WHEN 'London' THEN 1
            WHEN 'Edinburgh' THEN 2
            WHEN 'Cardiff' THEN 3
            ELSE 0
        END
    ");
DropColumn("dbo.People", "Location");
RenameColumn("dbo.People", "LocationTmp", "Location");

Ответ 2

На основе @JustAnotherUserYouMayKnow ответ, но проще.

Попробуйте сначала выполнить команду Sql(), а затем AlterColumn():

Sql(@"
    UPDATE dbo.People
    SET Location =
        CASE Location
            WHEN 'London' THEN 1
            WHEN 'Edinburgh' THEN 2
            WHEN 'Cardiff' THEN 3
            ELSE 0
        END
    ");
AlterColumn("dbo.People", "Location", c => c.Int(nullable: false));