您可以使用 Entity Framework 6 从主键中删除 Identity 吗?

tom*_*dox 6 c# entity-framework sql-server-2008 entity-framework-6

我通过实体框架代码优先创建了一个表,主键设置为自动递增,但现在我想从列中删除该自动递增。我已经尝试使用流畅的 API 做到这一点:

    public class ProductTypeMap: EntityTypeConfiguration<ProductType>
    {
        public ProductTypeMap()
        {
            // This is an enum effectively, so we need fixed IDs
            Property(x => x.ProductTypeId)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        }

    }
Run Code Online (Sandbox Code Playgroud)

还有一个注释:

    public class ProductType
    {
        [Required, Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int ProductTypeId { get; set; }
        public string ProductTypeName { get; set; }

    }
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,它们都生成相同的迁移代码:

    public partial class removeproducttypeidentity : DbMigration
    {
        public override void Up()
        {
            DropPrimaryKey("dbo.ProductTypes");
            AlterColumn("dbo.ProductTypes", "ProductTypeId", c => c.Int(nullable: false));
            AddPrimaryKey("dbo.ProductTypes", "ProductTypeId");
        }
        
        public override void Down()
        {
            DropPrimaryKey("dbo.ProductTypes");
            AlterColumn("dbo.ProductTypes", "ProductTypeId", c => c.Int(nullable: false, identity: true));
            AddPrimaryKey("dbo.ProductTypes", "ProductTypeId");
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是,当我在数据库上运行该迁移时,未从 SQL Server 2008 数据库表中删除身份规范?

我还尝试按如下方式明确关闭迁移中的身份,但这也没有做到:

AlterColumn("dbo.ProductTypes", "ProductTypeId", c => c.Int(nullable: false, identity: false));
Run Code Online (Sandbox Code Playgroud)

还有另一种方法可以告诉 SQL 删除身份吗?

Tra*_*hou 7

如果您想删除身份,您需要

步骤 1. 对键列进行注释

[DatabaseGenerated(DatabaseGeneratedOption.None)]

public short Id { get; set; }
Run Code Online (Sandbox Code Playgroud)

这将生成迁移脚本

AlterColumn("dbo.TableName", "Id", c => c.Long(nullable: false));
Run Code Online (Sandbox Code Playgroud)

但此脚本不会从键列中删除身份。

步骤 2. 在 SQL Management Studio 中手动从键列中删除标识。您不需要备份数据库。 在此输入图像描述

如果出现错误,您可能需要转到“工具”->“选项”->“设计器”,然后取消选中“防止保存需要重新创建表的更改” 在此输入图像描述


tom*_*dox 6

正如其他人所说,EF 本身无法做到这一点,尽管它会创建一个迁移脚本,使其看起来像这样。我已经尝试了很多方法来做到这一点,我发现最简单的方法是:

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

然后,这应该会为您提供一个删除身份的迁移,并且可以在数据库的其他副本上成功运行。

注意:Down生成的方法也不起作用,因为它将重新添加身份,而 EF 也无法做到这一点。如果您需要该Down方法来工作,请创建您添加的 SQL 的副本,并对其进行调整以再次创建具有该标识的表。

上面的方法是 @Georg Patscheider 在他的回答中描述得如此好的一种快速方法。


Geo*_*der 3

您不能用于ALTER COLUMN设置列是否为标识列(如何将列更改为标识(1,1))。

\n\n

相反,你必须:

\n\n
    \n
  • (备份数据库)
  • \n
  • CREATETMP_table 包含原始表的列,但 ID 列设置为identity: false
  • \n
  • SET IDENTITY_INSERT [TMP_Table] ON
  • \n
  • 将数据从原始表复制到 TMP 表
  • \n
  • SET IDENTITY_INSERT [TMP_Table] OFF
  • \n
  • DROP原表
  • \n
  • 将 TMP_table 重命名为原始表名 ( EXECUTE sp_rename)
  • \n
\n\n

提示:更改 SQL Management Studio 中的列并检查发出的脚本(SQL SERVER \xe2\x80\x93 添加或删除列上的标识属性)。

\n