Entity Framework 5 - Why is Entity State "Modified" after PropertyValue is set back to Original

c# entity-framework

Question

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.

using (TestDbContext context = new TestDbContext())
        {
            string name = context.Person.First().Name;

            // count is 0
            int count = context.ChangeTracker.Entries().Count(e => e.State == EntityState.Modified);

            // Change Value
            context.Person.First().Name = "Test";

            // count is 1 
            count = context.ChangeTracker.Entries().Count(e => e.State == EntityState.Modified);

            // Revert Value
            context.Person.First().Name = name;


            context.ChangeTracker.DetectChanges();

            // count is 1 
            count = context.ChangeTracker.Entries().Count(e => e.State == EntityState.Modified);
        }

Why? :(

1
9
11/22/2012 2:49:56 PM

Accepted Answer

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.

16
11/22/2012 2:55:25 PM

Popular Answer

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);
    }


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow