Reputation: 3167
I am trying to figure out how to make EntityFramework think that current state of the entity is unchanged.
The reason I try to do it is that entity is connected to a "template" entity (1 to 1 relation) from which it inherits values if these are null for the current entity.
The template property inheritance occurs when ObjectMaterialized event is executed and this is when the entity state becomes EntityState.Modified.
Now setting it's state to EntityState.Unchanged does not work (State is still modified, should it behave like this ?). I tried to resolve this problem by calling Detach and Attach but several referential issues exist as I suspect Entity Framework (6 pre) is finding duplicate relations.
The source of an issue seems to be the byte array property which among others I reset using following code:
var entry = context.Entry(this);
foreach(var p in entry.CurrentValues.PropertyNames.Where(p => entry.Property(p).IsModified))
{
if(entry.CurrentValues[p] is byte[])
{
entry.OriginalValues[p] = (entry.CurrentValues[p] as byte[])/*.ToArray()*/;
}
else
{
entry.OriginalValues[p] = entry.CurrentValues[p];
}
}
entry.State = EntityState.Unchanged;
When reading entry state using entry.State it becomes Modified again and entry.CurrentValues.PropertyNames.Where(x => entry.Property(x).IsModified) returns one entry: byte array. I compared arrays, they are identical ! I also tried assigning a clone of the array to OriginalValues[propertyName] without success.
My question is how to reset the entity state to Unchanged when it contains byte array for EF to think the object was retrieved from the database exactly as it is now ?
Upvotes: 1
Views: 3735
Reputation: 3167
Actually EntityFramework keeps track of all modified properties but it seems byte[] is an exception and it's only irreversibly marked as changed. I found an article about EF tracking: http://code.msdn.microsoft.com/How-to-undo-the-changes-in-00aed3c4 I solved the problem by not changing byte[] properties at all (as I can afford it because such are only used for serialization which can be postponed until actual saving to the database takes place) and instead of changing, only marking the object as modified which seems to to the job:
if(context.Entry(o).State == EntityState.Unchanged)
{
context.Entry(o).State = EntityState.Modified;
}
Upvotes: 0
Reputation: 9725
ObjectStatemanager only records if an item has been changed. It doesn't reflect if the entry is the same as from the database, i.e. there is no magic involved.
Try something like:
ObjectStateEntry state = context.ObjectStateManager.GetObjectStateEntry(entity);
state.ChangeState(EntityState.Unchanged);
Upvotes: 2