【问题标题】:Migrate entity with updated DatabaseGeneratedOption in Entity-Framework在 Entity-Framework 中使用更新的 DatabaseGeneratedOption 迁移实体
【发布时间】:2015-05-27 01:33:38
【问题描述】:

我根据这篇文章创建了代码优先应用程序 - Code First to a New Database。现在我要为Blog.BlogId 更改DatabaseGeneratedOption。我用下一种方式改变了我的代码:

public class Blog
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int BlogId
    {
        get;set;
    }
    ...
}

并为此代码更新创建了迁移:

public override void Up()
{
    DropForeignKey("dbo.Posts", "BlogId", "dbo.Blogs");
    DropPrimaryKey("dbo.Blogs");
    AlterColumn("dbo.Blogs", "BlogId", c => c.Int(nullable: false, identity: false));
    AddPrimaryKey("dbo.Blogs", "BlogId");
    AddForeignKey("dbo.Posts", "BlogId", "dbo.Blogs", "BlogId", cascadeDelete: true);
}

据此,我更改了在 Main 函数中创建博客实体的代码(在此处添加了 BlogId。)

var blog = new Blog
{
    Name = name,
    BlogId = 110//it could be any other value that isn't represented in column
};

现在,当我尝试运行我的代码时,出现下一个异常:DbUpdateException 和下一条消息 - 当 IDENTITY_INSERT 设置为时,无法在表“博客”中插入标识列的显式值关闭。

另一方面,当我删除所有迁移并从更新的实体创建初始迁移并创建没有身份标志的数据库(不要尝试更新现有数据库)时,我的代码使用我的 BlogId 创建实体。

我的问题是,在实际项目中我创建了表,我不会重新创建整个表,只是不会更新键列。实体框架迁移怎么做?

【问题讨论】:

  • 如果您尝试使用 SSMS 执行此操作,它会创建一个新表并将所有数据复制到新表中。

标签: c# entity-framework entity-framework-migrations


【解决方案1】:

您正试图从列中删除 IDENTITY 属性,不幸的是,这通常不是微不足道的(至少对于 SQL Server,我认为这是不可能的)。

更多解释见:


最后几个链接还提供了一些关于如何自定义迁移以删除 IDENTITY 列并仍然保留数据的想法。例如,从最后一个链接:

在 SQL Server 中更改列的标识设置的步骤是:

  1. 删除所有指向我们正在更改的主键的外键约束
  2. 删除主键约束
  3. 重命名现有列(以便我们以后可以重新创建外键关系)
  4. 使用新的身份设置添加新的主键列
  5. 更新现有数据以保留以前的外键关系
  6. 如果新列是标识列,我们需要用新值更新所有外键列
  7. 如果新列没有标识,我们可以从之前的标识列中复制旧值
  8. 删除旧的主键列
  9. 添加主键约束
  10. 加回外键约束

http://romiller.com/2013/04/30/ef6-switching-identity-onoff-with-a-custom-migration-operation/

【讨论】:

  • 谢谢它的工作。我取下 AlterColumn(..) 并用 AddColumn(tempColumn) 替换它,运行 SQL(update)、DropColumn(oldColumn),最后是 RenameColumn(tempColumnToOld)
猜你喜欢
  • 1970-01-01
  • 2016-05-08
  • 2013-07-21
  • 2016-09-13
  • 2020-02-25
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
相关资源
最近更新 更多