Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get original Entity from ChangeTracker

Is there a way to get the original Entity itself from the ChangeTracker (rather than just the original values)?

If the State is Modified, then I suppose I could do this:

// Get the DbEntityEntry from the DbContext.ChangeTracker...

// Store the current values
var currentValues = entry.CurrentValues.Clone();

// Set to the original values
entry.CurrentValues.SetValues(entry.OriginalValues.Clone());

// Now we have the original entity
Foo entity = (Foo)entry.Entity;

// Do something with it...

// Restore the current values
entry.CurrentValues.SetValues(currentValues);

But this doesn't seem very nice, and I'm sure there are problems with it that I don't know about... Is there a better way?

I'm using Entity Framework 6.

like image 886
Eric Avatar asked Feb 21 '13 21:02

Eric


People also ask

How do I track changes in EF core?

EF Core change tracking works best when the same DbContext instance is used to both query for entities and update them by calling SaveChanges. This is because EF Core automatically tracks the state of queried entities and then detects any changes made to these entities when SaveChanges is called.

How do I turn off change tracking in Entity Framework?

In Entity Framework, change tracking is enabled by default. You can also disable change tracking by setting the AutoDetectChangesEnabled property of DbContext to false. If this property is set to true then the Entity Framework maintains the state of entities.

What is change tracking in Entity Framework?

Entity Framework supports automatic change tracking of the loaded entities during the life-time of the context. The DbChangeTracker class gives you all the information about current entities being tracked by the context.

How does EF core update work?

EF Core's change tracking creates snapshots when loading the entities, and then compares those snapshots to the instances to find out which properties changed. A second database roundtrip is performed to save all the changes.


1 Answers

Override SaveChanges of DbContext or just access ChangeTracker from the context:

foreach (var entry in context.ChangeTracker.Entries<Foo>())
{
    if (entry.State == System.Data.EntityState.Modified)
    {
        // use entry.OriginalValues
        Foo originalFoo = CreateWithValues<Foo>(entry.OriginalValues);
    }
}

Here is a method which will create a new entity with the original values. Thus all entities should have a parameterless public constructor, you can simply construct an instance with new:

private T CreateWithValues<T>(DbPropertyValues values)
    where T : new()
{
    T entity = new T();
    Type type = typeof(T);

    foreach (var name in values.PropertyNames)
    {
        var property = type.GetProperty(name);
        property.SetValue(entity, values.GetValue<object>(name));
    }

    return entity;
}
like image 84
Sergey Berezovskiy Avatar answered Oct 26 '22 08:10

Sergey Berezovskiy