我正在尝试实体框架4的代码优先(EF CodeFirst 0.8),并且遇到了一个问题,其中一个简单的模型具有1< - >。 0 {1关系,介于Person
和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; }
}
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()
。数据库表为People
和Profiles
。 PersonId
是People
的PK,是一个自动增量标识。 ProfileId
是Profiles
的PK,是自动身份标识。 PersonId
是Profiles
的非空int列。
我做错了什么?我认为我遵守所有EF Code First关于配置规则的约定。
答案 0 :(得分:48)
我收到以下错误: 当IDENTITY_INSERT设置为OFF时,无法在表'People'中为identity列插入显式值。
我认为IDENTITY_INSERT是关闭的自动增量功能。 因此,请检查数据库中的PersonId字段以查看它是否为标识。
此外,也许这也可以解决你的问题。
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PersonId { get; set; }
答案 1 :(得分:34)
如果执行以下步骤,则会发生这种情况:
实体模型和数据库不同步。刷新模型将解决它。我昨天必须这样做。
答案 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的情况。
没有直接的方法来刷新模型,但是可以通过两个步骤实现相同的效果。
[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。
答案 7 :(得分:1)
在EF6中遇到此错误,查看了数据库,并且Identity Specification
设置为Yes
后所有内容都正常。然后,我删除了不同的迁移,并从当前模型进行了一次新的迁移,然后一切都开始工作了。自应用程序尚未生效并仍处于开发阶段以来最快的解决方案。
无法在表中插入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);