10

私は EF5 を使用していますが、このエンティティの唯一の変更された PropertyValue を元の値に戻した後、エンティティの状態が "変更済み" になっている理由がわかりません。

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

なんで?:(

4

3 に答える 3

17

Entity Frameworkは、データが変更された場合にのみ追跡し、元のコンテンツと異なる場合は追跡しないためです。

気の利いた方法を使用して、エンティティが変更されていないときに状態を未変更にリセットします。

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

このメソッドはEF4.0用であり、DbContextを使用する新しいバージョン用ではないことに注意してください。しかし、EF 4.1以降を使用するように書き直すことは問題ありません。私はすでにこれを自分で行っていますが、現在コードを見つけることができません。

于 2012-11-22T14:55:25.960 に答える
5

ヒントの Thx :)

これが私のEF5(DbContext)ソリューションです。ChangeTracker.Entries() から取得したすべての DbEnityEntry に対してこのメ​​ソッドを呼び出します

    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);
    }
于 2012-11-22T15:29:57.783 に答える