在 Entity Framework Core 中,如果在 SaveChanges 之前对一个实体类的主键属性(被映射为主键列)进行了赋值(非默认值)操作,EF Core 就会将该值插入数据库,从而引发异常:
Cannot insert explicit value for identity column in table 'xxx' when IDENTITY_INSERT is set to OFF.
请问是否有办法强制让 EF Core 始终不对主键列(自增列)进行插入数据操作?
EF 6 可以通过 .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
实现,EF Core 中未找到实现方法,相关链接:Gotcha inserting entities with explicit ID generated in database in Entity Framework Core 2 compared to Entity Framework 6
对主键列不自增长不是可以在映射时设置?dudu老大想要的是全局设置?
不是不自增长
,是始终自增长
@dudu: 使用【ValueGeneratedOnAdd】这个也不行??
@dudu: 是否可以结合DataAnnotations,在对应主键上添加【 [DatabaseGenerated(DatabaseGeneratedOption.Identity)]】,这样是否可行?
@Jeffcky: 不行
// Summary:
// Configures a property to have a value generated only when saving a new entity,
// unless a non-null, non-temporary value has been set, in which case the set value
// will be saved instead. The value may be generated by a client-side value generator
// or may be generated by the database as part of saving the entity.
//
// Returns:
// The same builder instance so that multiple configuration calls can be chained.
public virtual PropertyBuilder<TProperty> ValueGeneratedOnAdd();
@dudu: 可以结合DataAnnotations,在对应主键上添加【 [DatabaseGenerated(DatabaseGeneratedOption.Identity)]】,这样可行否?
@Jeffcky: 试过了,也是不行
@dudu: 是不行,这个特性和ValueGeneratedOnAdd是一样的。
@dudu:详细看了下,在ef core没有对应如ef 6.x中配置的方式,ef 6.x即使显式给了值,也会覆盖使用数据库自增长列,但在ef core中则会抛异常。当前能想到比较别扭的方式是通过追踪图来设置如果在添加时存在值时通过IsKeySet可得到,然后将其主键置为0,如下:
context.ChangeTracker.TrackGraph(blog, node =>
{
if (node .Entry.IsKeySet)
{
blog.Id = 0;
context.Blogs.Add(blog);
}
});
context.SaveChanges();
将其封装一下,可以实现,嘿嘿。
@Jeffcky: 目前只能采取这个变通方法了
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long Id { get; set; }
EF.Core 支持这种方式,EntityFramework,没了解过