i use the EF5 and don\'t know why a entity has the state \"modified\" after i set the only changed PropertyValue of this entity back to the original value.
Because Entity Framework only keeps track if the data got modified, not if it's different from it's original content.
We use a nifty method to reset the state to unmodified when the entity is unchanged:
public static void CheckIfModified(EntityObject entity, ObjectContext context)
{
if (entity.EntityState == EntityState.Modified)
{
ObjectStateEntry state = context.ObjectStateManager.GetObjectStateEntry(entity);
DbDataRecord orig = state.OriginalValues;
CurrentValueRecord curr = state.CurrentValues;
bool changed = false;
for (int i = 0; i < orig.FieldCount && !changed; ++i)
{
object origValue = orig.GetValue(i);
object curValue = curr.GetValue(i);
if (!origValue.Equals(curValue) && (!(origValue is byte[]) || !((byte[])origValue).SequenceEqual((byte[])curValue)))
{
changed = true;
}
}
if (!changed)
{
state.ChangeState(EntityState.Unchanged);
}
}
}
Please note that this method is for EF 4.0, not for the newer versions with DbContext. But it is no problem to rewrite it to use EF 4.1+, I have done this myself already but I can't find the code right now.
Building on User1481065's answer, to overcome the possibility of an exception if any of OriginalValues
is null, try the below. I've assumed a context that may contain more than one entity that may have updates (which may not necessarily be actual changes in value).
_dirty = False
Dim oChanges As IEnumerable(Of DbEntityEntry(Of CsSetting)) = _dbContext.ChangeTracker.Entries(Of CsSetting)().Where(Function(r) r.State <> EntityState.Unchanged)
For Each c As DbEntityEntry(Of CsSetting) In oChanges
_dirty = c.OriginalValues.PropertyNames.Any(Function(n) (c.OriginalValues(n) Is Nothing And c.CurrentValues(n) IsNot Nothing) OrElse (c.OriginalValues(n) IsNot Nothing AndAlso Not c.OriginalValues(n).Equals(c.CurrentValues(n))))
If _dirty Then Exit For
Next c
Return _dirty
You may not need the loop and therefore the presetting of _dirty
.
Thx for the hint :)
here is my EF5 (DbContext) Solution. I call this method for every DbEnityEntry that i get from ChangeTracker.Entries()
private void CheckIfDifferent(DbEntityEntry entry)
{
if (entry.State != EntityState.Modified)
return;
if (entry.OriginalValues.PropertyNames.Any(propertyName => !entry.OriginalValues[propertyName].Equals(entry.CurrentValues[propertyName])))
return;
(this.dbContext as IObjectContextAdapter).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity).ChangeState(EntityState.Unchanged);
}