自增非键值实体框架核心2.0 [英] Auto increment non key value entity framework core 2.0
问题描述
我有一个对象,该对象的密钥存储为 GUID 和友好 ID,如下所示:
I've got an object that has a key stored as a GUID as well as a friendlyID, like this:
public class Job {
[Key]
public Guid Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int FriendlyId { get; set; }
public string Description { get; set; }
}
但是,当我尝试使用我的更新方法更新描述时:
However when I try to update description using my update method:
public void Update(Job job, Job jobParam) {
if (job == null) {
throw new AppException("Job does not exist");
}
//Update job properties
job.Description = jobParam.Description;
_context.Job.Update(job);
_context.SaveChanges();
}
我收到一条错误消息:
System.Data.SqlClient.SqlException:无法更新标识列'FriendlyId'
System.Data.SqlClient.SqlException: Cannot update identity column 'FriendlyId'
我已确保尝试更新正确的对象,但我不明白为什么friendlyID 会在未更改的情况下尝试更新.在网上查看时,我可以看到 EF 核心 1.1 中存在一个会导致此问题发生的错误,但与 2.0 或非键值无关.
I've made sure that the correct object is trying to be updated, but I can't understand why friendlyID would try to get updated when it has not been changed. When looking online I can see that there was a bug in EF core 1.1 that would cause this issue to occur, but nothing about 2.0 or about a value that isn't a key.
推荐答案
EF Core 中生成的属性的确切行为仍处于调整过程中.EF Core 2.0 引入了两个新的属性元数据属性 - BeforeSaveBehavior
和 AfterSaveBehavior
.没有数据注释/流畅的 API 来设置它们,默认情况下,它们是从值生成策略以及属性是否是键的一部分中隐含的.同时,它们会影响跟踪操作的行为.
The exact behavior of the generated properties in EF Core is still in a process of tweaking. EF Core 2.0 introduced two new property metadata properties - BeforeSaveBehavior
and AfterSaveBehavior
. There is no data annotation/fluent API for setting them and by default they are implied from value generating strategy and whether the property is part of the key. At the same time they affect the behavior of the tracking operations.
这里的问题是,对于不是键的一部分的标识列(即ValueGeneratedOnAdd
),AfterSaveBehavior
是保存
,进而使Update
方法将它们标记为已修改,进而生成错误的UPDATE
命令.
The problem here is that for identity columns (i.e. ValueGeneratedOnAdd
) which are not part of a key, the AfterSaveBehavior
is Save
, which in turn makes Update
method to mark them as modified, which in turn generates wrong UPDATE
command.
要解决这个问题,您必须像这样设置 AfterSaveBehavior
(在 OnModelCreating
覆盖中):
To fix that, you have to set the AfterSaveBehavior
like this (inside OnModelCreating
override):
modelBuilder.Entity<Job>()
.Property(e => e.FriendlyId)
.ValueGeneratedOnAdd()
.Metadata.AfterSaveBehavior = PropertySaveBehavior.Throw; // <--
更新:在 EF Core 3.0+ 中,许多元数据属性已被替换为 Get/Set
方法,因此只需使用相应的方法:
Update: In EF Core 3.0+ many metadata properties have been replaced with Get/Set
methods, so just use the corresponding method:
.Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Throw);
这篇关于自增非键值实体框架核心2.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!