【问题标题】:Set identity to the previous created column during migration在迁移期间将标识设置为先前创建的列
【发布时间】:2014-02-16 11:36:12
【问题描述】:

我有一个包含 CodeFirst 数据库(实体框架 6)和两个迁移步骤的项目。 在 Global.asax 的 Application_Start 中使用此代码自动更新数据库:

Database.SetInitializer(
          new MigrateDatabaseToLatestVersion<MyDBEntities, MyNamespace.Configuration>());

迁移的第一步是创建表:

CreateTable(
     "dbo.GalleryAlbum",
      c => new
      {
           Id = c.Int(nullable: false),
           //other columns.....
       })
       .PrimaryKey(t => t.Id);

CreateTable(
       "dbo.GalleryPics",
       c => new
       {
           Id = c.Int(nullable: false),
           //other columns.....
       })
       .PrimaryKey(t => t.Id)
       .ForeignKey("dbo.GalleryAlbum", t => t.AlbumId)
       .Index(t => t.AlbumId);

第二个迁移步骤是向创建的表添加身份:

AlterColumn("dbo.GalleryAlbum", "Id", c => c.Int(nullable: false, identity: true));
AlterColumn("dbo.GalleryPics", "Id", c => c.Int(nullable: false, identity: true));

当我运行应用程序时,我可以看到第二个迁移代码正在运行,关于两个迁移的信息被添加到 _MigrationHistory 表中,但是两个表中的列都没有改变(没有身份)。这是架构:

[Id]        INT             NOT NULL,
//other columns

第一次迁移的 Code First 类如下:

 public partial class GalleryAlbum
 {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
 }
 //GalleryPics is the same

这是第二个迁移步骤:

public partial class GalleryAlbum
 {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
 }
 //GalleryPics is the same

您能否告诉我,为什么没有将身份添加到这些列中以及如何解决?

谢谢。

更新: 生成对数据库的更新请求,我从 IDbCommandInterceptor 获得:

ALTER TABLE [dbo].[GalleryAlbum] ALTER COLUMN [Id] [int] NOT NULL
ALTER TABLE [dbo].[GalleryPics] ALTER COLUMN [Id] [int] NOT NULL

【问题讨论】:

    标签: c# entity-framework entity-framework-6 ef-code-first entity-framework-migrations


    【解决方案1】:

    根据接受的答案,如果您在最初创建表时可以包含身份,那么这将解决问题。但是,如果表已经存在,并且您可以访问 SSMS,那么我发现最简单的方法是:

    1. 备份数据库...
    2. 更改您的班级,以便在您的代码中具有标识
    3. 使用包管理器控制台 (add-migration [your migration name]) 生成迁移
    4. 在新生成的迁移中注释掉Up方法中的代码
    5. 添加新的代码行准备接收您将在下面生成的 SQL:Sql (@" ");
    6. 进入 SSMS 并确保它已设置为在更改表时生成脚本
    7. 在 SMSS 的表设计器中添加标识
    8. 在 SSMS 中保存表更改并复制生成的 SQL。 (该 SQL 使用数据制作表的副本,删除原始表,然后使用列上设置的标识重新创建原始表,然后将所有数据复制回来并再次添加所有外键和约束)
    9. 将刚刚复制的 SQL 粘贴到上面添加的代码中的语音标记之间。
    10. 运行迁移

    这应该会给您一个添加身份的迁移,并且可以成功地在数据库的其他副本上运行。

    注意:生成的Down 方法也不起作用,因为它将删除身份which EF also can't do。如果您需要 Down 方法来工作,请创建您添加的 SQL 的副本并对其进行调整以再次创建没有标识的表。

    【讨论】:

      【解决方案2】:

      您不能在 SQL Server 中将列更改为 Identity,请参阅 Adding an identity to an existing column

      改为尝试一步添加标识和列:

      CreateTable(
               "dbo.GalleryAlbum",
                c => new
                {
                    Id = c.Int(nullable: false, identity:true),
                    //other columns.....
                }).PrimaryKey(t => t.Id);
      

      【讨论】:

      • 是的,它有效。我有解决上述问题的方法。但是我想知道为什么以及什么条件会导致这个问题。
      • 您无法在 SQL Server stackoverflow.com/questions/1049210/…中将列更改为标识
      • 谢谢。我希望 EF6 可以重新创建表并解决此类任务。您能否将您的评论转换为答案或再次回复我的问题?我想将其标记为答案。
      • 您还可以更改列名并添加新的迁移。
      【解决方案3】:

      ALTER TABLE [Mytable] 添加约束 [PK_dbo.Mytable] 主键 (Id) 对我有用,如果 Id 在那里并且有适当的数据

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-28
        • 1970-01-01
        • 2016-01-20
        相关资源
        最近更新 更多