Вы получаете сообщение об ошибке типа коллизий, поскольку генерируемый миграция пытается сделать непосредственно ALTER COLUMN
на пораженные колоннах, чтобы изменить тип от Guid
к integer
, и это не представляется возможным, потому что Guid
значения не могут быть неявно преобразованы в integer
значения.
Вы должны вручную изменить свою миграцию. Удалите линии AlterColumn
. Чтобы перенести существующие идентификаторы курса без потери данных, вы можете временно переименовать существующие столбцы Guid
(добавив суффикс _Old
), создать новые столбцы с правильным новым именем и типом, заполнить содержимое в таблице отношений с правильными значениями, используя UPDATE
с SELECT
, и, наконец, удалить старые колонки:
public override void Up()
{
DropForeignKey("dbo.GroupCourses", "Course_Id", "dbo.Courses");
DropIndex("dbo.GroupCourses", new[] { "Course_Id" });
DropPrimaryKey("dbo.Courses");
DropPrimaryKey("dbo.GroupCourses");
//Removed: AlterColumn("dbo.Courses", "Id", c => c.Int(nullable: false, identity: true));
RenameColumn("dbo.Courses", "Id", "Id_Old"); //Added
AddColumn("dbo.Courses", "Id", c => c.Int(nullable: false, identity: true)); //Added
//Removed: AlterColumn("dbo.GroupCourses", "Course_Id", c => c.Int(nullable: false));
RenameColumn("dbo.GroupCourses", "Course_Id", "Course_Id_Old"); //Added
AddColumn("dbo.GroupCourses", "Course_Id", c => c.Int(nullable: false)); //Added
Sql(@"UPDATE gc SET gc.Course_Id = c.Id "
+ "FROM dbo.GroupCourses as gc "
+ "INNER JOIN dbo.Courses as c ON gc.Course_Id_Old = c.id_Old"); //Added
DropColumn("dbo.GroupCourses", "Course_Id_Old"); //Added
DropColumn("dbo.Courses", "Id_Old"); //Added
AddPrimaryKey("dbo.Courses", "Id");
AddPrimaryKey("dbo.GroupCourses", new[] { "Group_Id", "Course_Id" });
CreateIndex("dbo.GroupCourses", "Course_Id");
AddForeignKey("dbo.GroupCourses", "Course_Id", "dbo.Courses", "Id", cascadeDelete: true);
}
Я пометил в коде строки, я изменил с комментариями //Added
и //Removed
. Остальная часть кода является исходной в миграции, сгенерированной с Add-Migration
после изменения типа свойства на int
в модели.
Вы должны заполнить только значениями в столбце таблицы взаимосвязей. UPDATE
. Значения в столбце Courses.Id
будут автоматически генерироваться, так как это столбец identity
.
Вы также должны выяснить метод Down()
и реализовать обратный процесс или оставить его как есть, если вы действительно никогда не собираетесь понижать базу данных до предыдущей миграции.
Вы также можете сделать это, разделив код между миграцией и сеялкой. Это было бы более правильно концептуально, поскольку вы должны использовать миграции для модификаций схемы и сеялки для модификации данных. Но я думаю, что это проще, и вам нужна только одна миграция, в то время как при использовании сеялки вам потребуются две миграции: одна со всем кодом, включенным выше, кроме UPDATE
и предложения, которые бросают столбцы _Old
, а другой с падением столбцов _Old
. Часть UPDATE
будет реализована в сеялке.
Предупреждение: код SQL, включенный в предложение UPDATE
, работает с Sql Server
, но может не работать с другими двигателями базы данных. Это еще один недостаток использования миграции вместо сеялки.
Не удалось выполнить переход, чтобы добавить CourseTemp, который возвращает все данные из старой таблицы курса в Temp с помощью метода 'Seed()'? Затем вы можете выполнить другую миграцию, чтобы удалить исходный курс и переименовать класс/таблицу CoureseTemp? – Bwolfing