EF Code First给我错误当IDENTITY_INSERT设置为OFF时,无法在表'People'中为identity列插入显式值。

时间:2011-01-13 16:34:05

标签: entity-framework entity-framework-4

我正在尝试实体框架4的代码优先(EF CodeFirst 0.8),并且遇到了一个问题,其中一个简单的模型具有1< - >。 0 {1关系,介于PersonProfile之间。以下是它们的定义:

public class Person
{
    public int PersonId { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime? DOB { get; set; }

    public virtual Profile Profile { get; set; }
}

public class Profile
{
    public int ProfileId { get; set; }
    public int PersonId { get; set; }
    public string DisplayName { get; set; }

    public virtual Person Person { get; set; }
}

DB上下文如下所示:

public class BodyDB : DbContext
{
    public DbSet<Person> People { get; set; }   
}

我没有为DbSet定义Profile,因为我认为People是其聚合根。当我尝试使用此代码添加新的Person - 即使没有Profile的人:

public Person Add(Person newPerson)
{
    Person person = _bodyBookEntities.People.Add(newPerson);
    _bodyBookEntities.SaveChanges();
    return person;
}

我收到以下错误:

  

当IDENTITY_INSERT设置为OFF时,无法在表'People'中为identity列插入显式值。

当我呼叫newPerson时,0对象的PersonId属性为People.Add()。数据库表为PeopleProfilesPersonIdPeople的PK,是一个自动增量标识。 ProfileIdProfiles的PK,是自动身份标识。 PersonIdProfiles的非空int列。

我做错了什么?我认为我遵守所有EF Code First关于配置规则的约定。

11 个答案:

答案 0 :(得分:48)

  

我收到以下错误:   当IDENTITY_INSERT设置为OFF时,无法在表'People'中为identity列插入显式值。

我认为IDENTITY_INSERT是关闭的自动增量功能。 因此,请检查数据库中的PersonId字段以查看它是否为标识。

此外,也许这也可以解决你的问题。

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PersonId { get; set; }

答案 1 :(得分:34)

如果执行以下步骤,则会发生这种情况:

  1. 在表格上创建非身份PK字段。
  2. 从该表中推断实体模型。
  3. 返回并将PK身份设置为true。
  4. 实体模型和数据库不同步。刷新模型将解决它。我昨天必须这样做。

答案 2 :(得分:11)

如果您正在使用EF Code First,那么除了将[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]注释属性添加到model.cs文件之外,其他人在此处建议,您需要对modelMap.cs文件进行相同的有效更改(流畅的映射说明):

更改自:

this.Property(t => t.id)
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

为:

this.Property(t => t.id)
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

(我使用EF Power Tools生成实体模型和默认映射文件,然后将一个Id列转换为prmary键列并在Sql Server中将其设置为IDENTITY,因此,我必须更新属性和默认的映射文件。)

如果你不在两个地方都改变它,你仍然会得到同样的错误。

答案 3 :(得分:4)

我没有遇到此问题直到我添加了一个复合键,所以一旦我有2个主键,就会出现 EF 6.xx

On my Key&#34; Id&#34; 标识规范设置为true 我需要添加

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]

现在的模型属性:

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[Key, Column("Id", Order = 1)]
public int Id { get; set; }

[Key, Column("RanGuid", Order = 2)]
public string RanGuid { get; set; }

答案 4 :(得分:3)

您的情况提醒我,当PrimaryKey和ForeignKey是同一列时,我遇到EF Code First的情况。

没有直接的方法来刷新模型,但是可以通过两个步骤实现相同的效果。

  1. 在Profile类中注释掉ProfileId。重新编译和更新数据库。
  2. 取消注释Profile Id,添加DatabaseGeneratedAttribute并再次更新数据库。
  3. [DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key]

    这样生成的ProfileId列就变为没有标识的密钥。

答案 5 :(得分:2)

为了搜索者的利益:我收到了此错误,但上述修复程序无效。这是由于我的错误。

在我的表上,我有Guid主键(非群集)和int索引。

尝试更新“发布”时发生错误。与博客&#39; info作为导航属性。见下面的课程:

public class Blog
{
    public Guid BlogId { get; set; }

    public int BlogIndex { get; set; }

    // other stuff
}

public class Post
{
    public Guid PostId { get; set; }

    public int PostIndex { get; set; }

    // other stuff

    public Blog Blog { get; set; }
}

问题在于,当我将DTO转换为模型时,BlogId被更改为new Guid()(我在映射中出错)。产生的错误与此问题中详述的错误相同。

要修复它,我需要在插入时检查数据是否正确(它不是)并修复了错误的数据更改(在我的情况下,是破坏的映射)。

答案 6 :(得分:1)

这是解决方案。另请参阅附件以获取更多帮助。

导航至您的EF模型“.edmx”文件&gt;&gt;打开它&gt;&gt;现在右键单击图表并选择“从数据库更新模型”。

这将修复它,因为您在创建EF模型后在数据库中创建了PK。

help to recreate steps stated above

答案 7 :(得分:1)

在EF6中遇到此错误,查看了数据库,并且Identity Specification设置为Yes后所有内容都正常。然后,我删除了不同的迁移,并从当前模型进行了一次新的迁移,然后一切都开始工作了。自应用程序尚未生效并仍处于开发阶段以来最快的解决方案。

enter image description here

  

无法在表中插入identity列的显式值   当IDENTITY_INSERT设置为OFF时'测试'。

答案 8 :(得分:1)

如果您正在使用EF核心和像我这样的流畅界面,我发现我曾经使用Scaffold-DbContext实用程序从现有数据库创建模型,为我的列生成一行的是:

entity.Property(e => e.id).ValueGeneratedNever();

在我更改了将IDENTITY属性添加到我的ID的数据库之后,我不得不更改以下行:

entity.Property(e => e.id).ValueGeneratedOnAdd();

除了将[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key]装饰器添加到我的模型类中的id字段之外。

我甚至不确定后者是否有必要。解决了以前的修复后,我没有尝试删除它。

答案 9 :(得分:0)

在我的情况下,似乎EF不喜欢 INT 身份字段以外的其他类型 - 我的是 BYTE (SQL端的TINYINT)。

由于我能够在SQL上更新我的项目并将其更改为 INT ,因此在VisualStudio上重新运行逆向工程代码优先后,错误立即停止发生。

答案 10 :(得分:0)

  

在我的情况下,似乎EF不像INT身份字段那样喜欢其他类型 - 我的是BYTE(SQL端的TINYINT)。

我也使用了tinyint类型的PK这个错误。并不是EF不喜欢它,似乎与其他情况不同,你必须在你的配置中指定这样:

this.Property(t => t.TableID).HasColumnName("TableID").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);