例如,我有一张下表:
CREATE TABLE Person (
id int IDENTITY(1,1) NOT NULL PK,
firstName nvarchar(20) NOT NULL,
lastName nvarchar(30) NOT NULL,
birtdate datetimeoffset(7) NOT NULL,
age int,
height int,
)
实体映射的一部分:
public void Configure(EntityTypeBuilder<Person> builder)
{
...
builder.HasKey(k => k.Id);
builder.Property(k => k.Id)
.ValueGeneratedOnAdd()
.IsRequired();
...
}
我有MS SQL Server,客户端具有该表,服务器端具有相同的表。我的程序从客户端上的表中检索数据,并将其发送到服务器,在服务器上将数据添加到数据库。 检索数据期间没有问题,但是当我尝试插入数据时出现错误:
SqlException: Cannot insert explicit value for identity column in table 'Person' when IDENTITY_INSERT is set to OFF.
尽管有.ValueGeneratedOnAdd()
检索数据时,我会获得具有填充的ID属性(1、2、3等)的实体,但是我认为这没关系。
答案 0 :(得分:2)
检索数据时,我会获得具有填充的ID属性(1、2、3等)的实体,但是我认为这没关系。
实际上,它确实很重要,并且是问题的原因。 ValueGenerated
对于将值设置为非默认值的属性无效(null
对于可空类型,0
对于数字类型等)。
该行为在EF Core文档的Generated Values部分中进行了说明:
如果将具有为该属性分配值的实体添加到上下文,则EF将尝试插入该值,而不是生成一个新值。如果未分配属性的CLR默认值({{1}的
null
,string
的{{1}},{{1} {1}}等。有关更多信息,请参见Explicit values for generated properties。
基本上,这是允许您在上载数据时使用所谓的“身份插入”方案。有关更多信息,请参见Explicit values into SQL Server IDENTITY columns。
话虽如此,如果您不希望这种行为,请确保在调用将实体添加到数据库上下文/集之前,将所有实体0
(PK)属性都设置为int
答案 1 :(得分:2)
我解决了在Id属性的配置中添加UseSqlServerIdentityColumn()
的问题:
builder.Property(k => k.Id)
.ValueGeneratedOnAdd()
.UseSqlServerIdentityColumn()
...
请注意,它是 Microsoft.EntityFrameworkCore.SqlServer 包中SqlServerPropertyBuilderExtensions
的一部分。