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

How*_*ley 42 entity-framework entity-framework-4

我正在尝试实体框架4的代码优先(EF CodeFirst 0.8),并且遇到一个问题,一个简单的模型,在Person和之间有一个1 - - > 0..1的关系Profile.以下是它们的定义方式:

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; }
}
Run Code Online (Sandbox Code Playgroud)

DB上下文如下所示:

public class BodyDB : DbContext
{
    public DbSet<Person> People { get; set; }   
}
Run Code Online (Sandbox Code Playgroud)

我没有定义DbSetfor,Profile因为我认为People它是它的聚合根.当我尝试添加一个新的Person- 即使没有Profile这个代码的一个:

public Person Add(Person newPerson)
{
    Person person = _bodyBookEntities.People.Add(newPerson);
    _bodyBookEntities.SaveChanges();
    return person;
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

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

newPerson对象有一个0PersonId财产当我打电话People.Add().数据库表是PeopleProfiles.PersonId是PK People并且是自动增量标识.ProfileId是PK Profiles并且是自动身份.PersonId是一个非null的int列Profiles.

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

Sam*_*djo 50

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

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

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

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PersonId { get; set; }
Run Code Online (Sandbox Code Playgroud)

  • 有同样的问题,我通过在 DbContext 中的 OnModelCreating 覆盖上设置 DatabaseGeneratedOption.Identity 来修复它 (2认同)

Chr*_*ens 35

如果您执行以下步骤将发生这种情况:

  1. 在表上创建非标识PK字段.
  2. 从该表中推断实体模型.
  3. 返回并将PK标识设置为true.

实体模型和数据库不同步.刷新模型将解决它.我昨天必须这样做.

  • 你如何刷新模型? (6认同)
  • 但是,我正在使用EF4的Code First模型; 没有EDMX文件.EF通过模型类的命名约定将CSDL推断为SSDL映射.还有一个流畅的接口来覆盖惯例 - 我在这里没有使用过,因为我认为在这个特定的实例中我不需要它. (3认同)
  • 所以,这里的基本问题是EF应该生成一个没有PersonId的INSERT语句,但它不是(一个Profiler也可能有用).我不熟悉EF4以了解身份标志的维护位置,但在模型的某个地方,模型并不知道PersonId是Identity.对不起,我没有更多的帮助. (2认同)

Mat*_*lay 11

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

改变自:

this.Property(t => t.id)
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Run Code Online (Sandbox Code Playgroud)

至:

this.Property(t => t.id)
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Run Code Online (Sandbox Code Playgroud)

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

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


GSo*_*ing 7

当 PrimaryKey 和 ForeignKey 是同一列时,您的情况让我想起了我在 EF Code First 中遇到的情况。

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

  1. 注释掉 Profile 类中的 ProfileId。重新编译和更新数据库。
  2. 取消注释配置文件 ID,添加 DatabaseGeneratedAttribute 并再次更新数据库。

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key]
Run Code Online (Sandbox Code Playgroud)

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


Ema*_*tti 6

如果您像我一样使用 EF core 和流畅的界面,我发现我用来从现有数据库创建模型的 Scaffold-DbContext 实用程序会为我的列生成一行,如下所示:

entity.Property(e => e.id).ValueGeneratedNever();
Run Code Online (Sandbox Code Playgroud)

在我更改数据库并将 IDENTITY 属性添加到我的 id 后,我必须更改以下行:

entity.Property(e => e.id).ValueGeneratedOnAdd();
Run Code Online (Sandbox Code Playgroud)

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

我什至不确定后者是否有必要。在使用前一个修复程序解决后,我没有尝试删除它。