ef-code-first - Entity Framework 代码优先迁移 : Set Primary Key Value

标签 ef-code-first primary-key entity-framework-5 entity-framework-migrations

我有一个表,它为表的某些行存储一些额外的数据,例如:

public class QuoteExtra
{
    [Key]
    public int QuoteId { get; set; }
    // More fields here
}

我希望能够在我明确设置 PK 的表中添加行。

如果我只是像上面那样简单地保留它,设置一个值并提交该行会导致该值被丢弃并替换为数据库中自动生成的值(并且该列被定义为实际模式中的 Identity 列)。

这似乎是正确的解决方案:
public class QuoteExtra
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int QuoteId { get; set; }
    // More fields here
}

然而,这反而让我异常(exception):

Cannot insert explicit value for identity column in table 'EnumTest' when IDENTITY_INSERT is set to OFF.



那么,如何编写我的类(class)以便能够在 EF 中设置主键的值?

编辑:

我尝试添加以下基于代码的迁移以将 IDENTITY_INSERT 设置为 ON:
public override void Up()
{
    Sql("SET IDENTITY_INSERT QuoteExtra ON");
}

我运行它并再次尝试,但得到与上述相同的异常。奇怪的是数据库确实反射(reflect)了这个设置,并且直接对它运行 SQL 确实允许我为主键插入任意值 - 所以看起来 Entity Framework 本身正在执行这个规则,并且忽略了识别 IDENTITY_INSERT 不在事实设置为关闭。我需要在 EF 本身的某个地方设置它吗?

编辑2:

我误解了 IDENTITY_INSERT;我假设设置它曾经无限期地留在那张 table 上。实际上,它与“ session ”一样长,这意味着例如将其设置在迁移中意味着它存在……只要迁移运行,并且与我后来的 .Add() 与 EF 的 future 连接无关,这就解释了为什么我仍然得到那个异常 - 数据库确实是异常的来源,而不是 EF。由于 IDENTITY_INSERT 被限制为每个 session 最多一个表,这是一种相当低效的方法 - 首先不创建 Identity PK 列似乎是一条更好的路线。

最佳答案

这是在未启用身份自动增量的情况下创建 PK 的正确方法:

public class QuoteExtra
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int QuoteId { get; set; }
    // More fields here
}

但是,如果在 EF Migrations 已经创建表之后添加 DatabaseGenerated(DatabaseGeneratedOption.None)],它不会对表执行任何操作。如果这是您的场景,您需要添加手动迁移以删除表:
add-migration RecreateQuoteExtra

在迁移中:
public override void Up()
{
    DropTable("QuoteExtra");
}

然后,EF 自动迁移将自动重新创建没有身份约束的表,这将允许您随时设置 PK 值,而无需运行任何特殊命令,例如 IDENTITY_INSERT ON。

这听起来像 EF7(“数据运动”)中出现的破坏性较小的方法,或者如果您想避免丢失现有数据,您可以在迁移中自己编写大量手动 sql 来创建临时表并移动数据在表中。

编辑:根据您的情况,EF Migrations 可能不会重新创建表 - 如果该类已经存在并且已经添加到您的 DbContext 中,它只会删除它并保留它,这意味着您的手动迁移不仅要删除而且还要创建 table 。没什么大不了的,因为 EF Migrations 从 add-migration 为您生成的脚手架代码将为您创建这些语句,但它需要更多代码来检查问题。

关于ef-code-first - Entity Framework 代码优先迁移 : Set Primary Key Value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15509564/

相关文章:

.net - 添加迁移给出文件名已经存在

.net - Model First with DbContext,无法初始化新的数据库

asp.net - "Update-DataBase"无法使用 Asp BoilerPlate 模块零(代码优先)工作

sql - SQL Server中的GUID是什么数据类型?

mysql - 多个主键

entity-framework - Entity Framework 5 - "Conflicting Changes Detected"

c# - 无法删除该对象,因为在 Entity Framework 5 中的 ObjectStateManager 中找不到它

c# - UnitOfWork类的结构图及生命周期

sql-server-2008 - 从存储过程插入返回 GUID

c# - 如果使用 Entity Framework 与列表中的任何匹配