在迁移期间将标识设置为先前创建的列

时间:2014-02-16 11:36:13

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

我有一个包含CodeFirst数据库(Entity Framework 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表中,但两个表中的列都没有更改(没有Identity)。这是架构:

[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

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分:2)

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

  1. 备份数据库......
  2. 更改您的课程,以便在您的代码中具有身份
  3. 使用程序包管理器控制台(Up
  4. 生成迁移
  5. 在新生成的迁移
  6. 中注释Sql (@" ");方法中的代码
  7. 添加一行新代码,以便接收您将在下面生成的SQL:Down
  8. 进入SSMS并确保在进行表格更改时将其设置为生成脚本
  9. 在SMSS中的表设计器中添加标识
  10. 在SSMS中保存表更改并复制生成的SQL。 (该SQL使用数据创建表的副本,删除原始表,然后使用列上的标识设置重新创建原始表,然后将所有数据复制回来并重新添加所有外键和约束)< / LI>
  11. 将您刚刚复制的SQL粘贴到上面添加的代码中的语音标记之间。
  12. 运行迁移
  13. 然后应该为您提供添加标识的迁移,并且可以成功地在数据库的其他副本上运行。

    注意:生成的Down方法无效,因为它将删除标识which EF also can't do。如果您需要function y = lagrangian(X, Y, x) if length(X) ~= length(Y); error('X and Y must have the same length.'); end y = zeros(size(x)); for i = 1:length(X) L = ones(size(x)); for j = [1:i-1 i+1:length(X)] L = L.*(x-X(j))/(X(i)-X(j)); end y = y+Y(i)*L; end 方法来创建您添加的SQL的副本并进行调整以创建没有该标识的表。

答案 2 :(得分:0)

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