实体框架代码首次迁移:设置主键值 [英] Entity Framework Code First Migrations: Set Primary Key Value

查看:88
本文介绍了实体框架代码首次迁移:设置主键值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表格可以存储一些表格的一些额外的数据,例如:

I have a table that stores some extra data for some rows of a table like:

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

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

I'd like to be able to add rows to this table where I explicitly set the PK.

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

If I simply leave it as above, setting a value and submitting the row causes the value to be discarded and replaced with the auto-generated value from the database (and the column is defined as an Identity column in the actual schema).

这似乎是正确的解决方案:

This appears to be the right solution:

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

例外:


当IDENTITY_INSERT设置为OFF时,无法在表EnumTest中插入标识列的显式值。

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

那么,我如何写我的课程,以便我可以在EF中设置主键的值?

So, how do I write my class so that I'm able to set the value of a Primary Key in EF?

编辑:

我尝试添加以下基于代码的迁移,将IDENTITY_INSERT设置为ON:

I tried adding the following Code-based Migration to set IDENTITY_INSERT to ON:

public override void Up()
{
    Sql("SET IDENTITY_INSERT QuoteExtra ON");
}

我运行它,再次尝试,但是有与上述相同的异常。奇怪的是,数据库反映了这种设置,并且直接对其运行SQL可以允许我为主键插入任意值 - 所以它会出现在Entity Framework本身正在执行这个规则,而忽略了识别IDENTITY_INSERT不在事实设置为关闭。我需要将其设置在EF本身吗?

I ran it and tried again, but got the same exception as above. What's strange is the database does reflect this setting, and running SQL against it directly does allow me to insert arbitrary values in for the primary key - so it would appear Entity Framework itself is enforcing this rule, and neglecting to recognize that IDENTITY_INSERT is not in fact set to off. Do I need to set it somewhere in EF itself?

编辑2:

我误解了IDENTITY_INSERT;我假设将它设置为无限期地放在该表上。事实上,只要会话生活,这意味着例如将其设置为迁移意味着它只会在迁移运行时生效,并且与未来的连接无关,如我以后的.Add()与EF ,这解释了为什么我还有这个例外 - 数据库真的是异常的来源,而不是EF。由于IDENTITY_INSERT每个会话最多只能包含一个表,所以执行此操作是一个非常低效的方法 - 首先,不要创建一个Identity PK列,这似乎是一个更好的路由。

I misunderstood IDENTITY_INSERT; I assumed setting it once left it on for that table indefinitely. In fact it lives as long as the "Session," meaning that for example setting it in a Migration means it lives... as long as that Migration runs, and has no bearing on future connections like my later .Add() with EF, which explains why I still got that exception - the DB really is the source of the exception, not EF. Since IDENTITY_INSERT is limited to at most one table per session it's a fairly inefficient way to do this - not creating an Identity PK column in the first place seems like a better route.

推荐答案

这是创建没有启用身份自动增量的PK的正确方法:

This is the proper way of creating a PK without Identity Autoincrement enabled:

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

但是,如果添加DatabaseGenerated (DatabaseGeneratedOption.None)]之后,EF迁移已经创建了表,它静静地对表进行任何操作。如果这是您的方案,您需要添加手动迁移以放下表:

However, if you add DatabaseGenerated(DatabaseGeneratedOption.None)] after EF Migrations has already created the table, it quietly does nothing to the table. If this is your scenario you need to add a manual migration to drop the table:

add-migration RecreateQuoteExtra

在迁移中:

public override void Up()
{
    DropTable("QuoteExtra");
}

EF自动迁移将自动重新创建表,而不需要Identity约束然后允许您随时设置PK值,而不必运行任何特殊命令,例如IDENTITY_INSERT ON。

EF Automatic Migrations will then automatically recreate the table without the Identity constraint, which will then allow you to set the PK value anytime, without having to run any special commands like IDENTITY_INSERT ON.

这听起来像是一个较少破坏性的方法来实现EF7 (Data Motion),或者您可以在迁移过程中自己编写大量手动sql,以创建临时表并移动数据,如果您想避免丢失表中的现有数据。

It sounds like a less destructive way to do this is coming in EF7 ("Data Motion"), or you could write a lot of manual sql yourself in the migration to create temp tables and move data around if you wanted to avoid losing existing data in the table.

编辑:根据您的情况,EF迁移可能无法重新创建表 - 如果类已存在并已添加到DbContext中,那么它将会丢弃它,因此您的手动迁移不仅仅需要掉下来也可以创建表。不是一个很大的事情,因为脚手架代码EF Migrations为您从添加迁移生成将为您创建这些语句,但它是一个更多的代码来检查问题。

Depending on your scenario EF Migrations might not recreate the table - if the class already exists and is already added to your DbContext it will just drop it and leave it at that, meaning your manual migration has to not only drop but also create the table. Not a big deal since the scaffolded code EF Migrations generates for you from add-migration will create these statements for you, but it is a bit more code to check over for issues.

这篇关于实体框架代码首次迁移:设置主键值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆