【问题标题】:How to alter column to identity using entity framework dbmigration?如何使用实体框架 dbmigration 将列更改为标识?
【发布时间】:2013-03-28 09:54:02
【问题描述】:

我使用 Entity Framework 5.0 和电动工具对一个小型数据库进行了逆向工程。然后我开始开发一个网站。我遇到了一个问题,因为我忘记将我的一个表上的 ID 列设为 IDENTITY 列。

所以我添加了一个代码优先迁移并在包管理器控制台中使用 update-database 命令运行它。这是我写的“Up”方法:

    public override void Up()
    {
        Sql("DELETE FROM dbo.Sections");
        Sql("DELETE FROM dbo.QuestionInstances");

        DropForeignKey("dbo.SectionInstances", "SectionID", "dbo.Sections");
        DropForeignKey("dbo.QuestionInstances", "SectionID", "dbo.Sections");

        DropTable("dbo.Sections");

        CreateTable(
            "dbo.Sections",
            c => new
            {
                ID = c.Int(nullable: false, identity: true),
                UniqueDescription = c.String(nullable: false, maxLength: 50),
                Heading = c.String(maxLength: 500),
            })
            .PrimaryKey(t => t.ID);

        AddForeignKey("dbo.SectionInstances", "SectionID", "dbo.Sections");
        AddForeignKey("dbo.QuestionInstances", "SectionID", "dbo.Sections");
    }

我检查了数据库,它已成功更改。

我期待实体框架更新其模型并停止显式设置 ID,但似乎我错了,因为当我尝试保存时,我现在收到此错误:“无法为表中的标识列插入显式值IDENTITY_INSERT 设置为 OFF 时的 'Sections'"

如何让实体框架识别该列现在是标识列?

【问题讨论】:

  • 您真的有代码优先模型,还是使用 EDMX 文件?
  • 我使用的是代码优先。没有 EDMX。
  • 好的 - 我猜你在某处配置了 DatabaseGeneratedOption.None 的 Id 属性。 Powertools 可能在第一次对数据库进行逆向工程时就这样做了,因此您必须手动删除它,因为您现在将它作为标识列。
  • @PeterHansen - 当然就是这样!我有一个 SectionMap.cs 类,它告诉框架如何映射到数据库....我已将其更改为:“ this.Property(t => t.ID) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);” (它确实有 DatabaseGeneratedOption.None)。请提出答案,以便我接受!

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


【解决方案1】:

由于您在 Id 列尚未设置为 IDENTITY 时对数据库进行了逆向工程,因此已生成代码优先模型,并为实体上的 Id 属性设置了DatabaseGeneratedOption.None

这会导致 EF 创建一个带有 Id 集的插入语句,在将列更改为 IDENTITY 后该语句不再起作用。

您必须手动修复该配置,将其设置为 DatabaseGeneratedOption.Identity 或完全删除它,因为这是整数字段的默认值。

【讨论】:

  • 顺便说一句。当我更改 Map 类以匹配我手动创建的数据库迁移时,框架将其作为对模型的更改。所以我运行了添加迁移。它使用以下代码创建了一个 Up() 方法:"AlterColumn("dbo.Sections", "ID", c => c.Int(nullable: false, identity: true));" update-database -verbose 表明这会生成 sql "ALTER TABLE [dbo].[Sections] ALTER COLUMN [ID] [int] NOT NULL" - 它实际上并没有改变任何东西。正确的方法是 1.更改映射文件 2.调用 add-migration 3.更改生成的迁移代码删除并重新创建表
  • 是的,当然。通常的工作流程是更改代码优先模型,通过调用add-migration 使用更改构建迁移,然后通过调用update-database 更新数据库。迁移功能不会知道您手动更改了数据库,因此它也会创建一个迁移功能。您可以致电Add-Migration name –IgnoreChanges。这将创建一个忽略模型更改的空迁移。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 2023-03-10
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多