I've run into a Change Conflict Exception that I can't quite determine the reason for.
From the ChangeConflictException documentation:
Thrown when an update fails because database values have been updated since the client last read them.
In the case I'm looking at though, the database values haven't been modified. The only modifications taking place before the exception is being thrown are on the object in memory.
I initially had a database trigger which updated a timestamp on the record whenever it was modified. The trigger itself was causing a ChangeConflictException, so I removed it and instead extended the generated linq-to-sql dbml object in the following way:
public partial class TerribleName {
partial void OnCreated() {
PropertyChanged += RecordUpdated;
}
void RecordUpdated(object sender, PropertyChangedEventArgs e) {
//see if the field being updated was "LastUpdate"
if (e.PropertyName != "LastUpdate") {
this.LastUpdate = DateTime.Now; //this line triggers PropertyChanged again
}
}
}
I've employed this code based "trigger" a number of times, but in this case something is off (likely my own understanding).
I have a code block like this:
TerribleName name = new TerribleName();
name.First = "X Æ A-12"; //fires the trigger, updating the LastUpdate column (in memory)
name.Last = "Musk"; //fires the trigger, updating the LastUpdate column (in memory)
dbContext.TerribleNames.InsertOnSubmit(name);
dbContext.SubmitChanges(); //commits the record to the database
...
//a bunch of reads take place to validate the input - no modifications to the object happen
...
name.Validated = true; //fires the trigger, updating the LastUpdate column (in memory)
dbContext.SubmitChanges();//This now throws a ChangeConflictException
I just can't wrap my head around why this generates a Change Conflict Exception. Examining the exception, I can see that there are multiple Member conflicts, the first of which doesn't appear to be a conflict at all (Edit: it is in conflict, I didn't see the precision initially, have added it below):
First:
-occ.MemberConflicts[0] {System.Data.Linq.MemberChangeConflict} System.Data.Linq.MemberChangeConflict
CurrentValue {9/25/2020 10:44:26.6908779 AM} object {System.DateTime}
DatabaseValue {9/25/2020 10:44:26.6900000 AM} object {System.DateTime}
IsModified false bool
IsResolved false bool
Member {System.DateTime RecordDate} System.Reflection.MemberInfo {System.Reflection.RuntimePropertyInfo}
OriginalValue {9/25/2020 10:44:26.6908779 AM} object {System.DateTime}
Second:
-occ.MemberConflicts[1] {System.Data.Linq.MemberChangeConflict} System.Data.Linq.MemberChangeConflict
CurrentValue {9/25/2020 10:44:29.7227277 AM} object {System.DateTime}
DatabaseValue {9/25/2020 10:44:26.6930000 AM} object {System.DateTime}
IsModified true bool
IsResolved false bool
Member {System.Nullable`1[System.DateTime] LastUpdate} System.Reflection.MemberInfo {System.Reflection.RuntimePropertyInfo}
OriginalValue {9/25/2020 10:44:29.7072610 AM} object {System.DateTime}
It seems to me that I'm just assigning a new value to the LastUpdate column in memory, more or less the same way I assigned the Validated flag. Why is this causing a ChangeConflictException?
My best guess is that there is something different about the context in which the PropertyChanged event is running which changes how the assignment affects the consistency of the object. If this is the case, how can I avoid the problem?