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();
}
I get an error stating:
System.Data.SqlClient.SqlException: Cannot update identity column 'FriendlyId'
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.
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
andAfterSaveBehavior
. 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.The problem here is that for identity columns (i.e.
ValueGeneratedOnAdd
) which are not part of a key, theAfterSaveBehavior
isSave
, which in turn makesUpdate
method to mark them as modified, which in turn generates wrongUPDATE
command.To fix that, you have to set the
AfterSaveBehavior
like this (insideOnModelCreating
override):