Cómo obtener Entidad original de ChangeTracker

.net c# entity-framework entity-framework-6

Pregunta

¿Hay alguna forma de obtener la Entidad original desde el ChangeTracker (en lugar de solo los valores originales)?

Si se Modified el State , entonces supongo que podría hacer esto:

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

Pero esto no parece muy bueno, y estoy seguro de que hay problemas con los que no sé ... ¿Hay alguna forma mejor?

Estoy usando Entity Framework 6.

Respuesta aceptada

Reemplace SaveChanges of DbContext o simplemente acceda a ChangeTracker desde el contexto:

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

Aquí hay un método que creará una nueva entidad con los valores originales. Por lo tanto, todas las entidades deben tener un constructor público sin parámetros, simplemente puede construir una instancia con el new :

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

Respuesta popular

Bonito. Aquí hay una versión ligeramente modificada que manejará propiedades complejas:

public static TEntity GetOriginal<TEntity>(this DbContext ctx, TEntity updatedEntity) where TEntity : class
    {
        Func<DbPropertyValues, Type, object> getOriginal = null;
        getOriginal = (originalValues, type) =>
             {
                 object original = Activator.CreateInstance(type, true);
                 foreach (var ptyName in originalValues.PropertyNames)
                 {
                     var property = type.GetProperty(ptyName);
                     object value = originalValues[ptyName];
                     if (value is DbPropertyValues) //nested complex object
                     {
                         property.SetValue(original, getOriginal(value as DbPropertyValues, property.PropertyType));
                     }
                     else
                     {
                         property.SetValue(original, value);
                     }
                 }
                 return original;
             };
        return (TEntity)getOriginal(ctx.Entry(updatedEntity).OriginalValues, typeof(TEntity));
    }



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué