为什么在此实例中,为更新数据库生成的代码优先迁移会中断?

本文关键字:代码 迁移 中断 实例 数据库 更新 为什么 | 更新日期: 2023-09-27 18:03:17

我将我的一个实体从UploadedFile重命名为File并执行Add-Migration,结果如下:

    public override void Up()
    {
        RenameTable(name: "dbo.UploadedFiles", newName: "Files");
        DropPrimaryKey("dbo.UploadedFiles");
        AddColumn("dbo.Files", "FileId", c => c.Int(nullable: false, identity: true));
        AddPrimaryKey("dbo.Files", "FileId");
        DropColumn("dbo.Files", "UploadedFileId");
    }

之后,我执行了一个Update-Database,发现迁移将失败。我不得不重新排序两个语句,使其工作;

  1. DropPrimaryKey需要在RenameTable之前,因为生成的代码引用了旧的表名
  2. DropColumn需要在AddColumn之前执行,否则会抛出多个标识列错误。

结果如下:

        DropPrimaryKey("dbo.UploadedFiles");
        RenameTable(name: "dbo.UploadedFiles", newName: "Files");
        DropColumn("dbo.Files", "UploadedFileId");
        AddColumn("dbo.Files", "FileId", c => c.Int(nullable: false, identity: true));
        AddPrimaryKey("dbo.Files", "FileId");

我是否需要手工编辑这些生成的迁移,或者我是否做错了影响生成的事情?

是否一次更改表名和主键太多,我应该在每一步执行Add-Migration吗?

为什么在此实例中,为更新数据库生成的代码优先迁移会中断?

这听起来像是一个bug,我建议您在codeplex上创建一个问题。在创建迁移时,EF似乎无法确定哪个语句具有更高的优先级。

当然,如果您使用简单地将表上的PK命名为Id的惯例,则可以完全避免此问题。我通常发现这更可读,因为它可以防止pk与fk混合(例如IdOwnerId vs FileIdOwnerId)