2011-11-15 13 views

Respuesta

13

Se puede acceder a ellos a través de ObjectStateEntry

var originalValues = context 
     .ObjectStateManager.GetObjectStateEntry(myEntity).OriginalValues; 
+0

originalValues ​​es el tipo DbDataRecord. ¿Cómo convertirlo a tipo de entidad? – JatSing

+0

@Sun no tiene tipos de entidad. Necesita convertir los valores al tipo apropiado. ej. 'var name = (string) originalValues ​​[" Name "];' – Eranga

27

@Eranga respuesta no está actualizado para EF 5. Por alguna razón, EF 5 no funciona bien cuando conseguir valores originales utilizando una sentencia como esta:

var originalValues = context.Entry(myEntity).OriginalValues; 

Mi solución de trabajo utiliza AsNoTracking() método de DbSet, como el siguiente ejemplo:

var originalEntity = context.MyEntities.AsNoTracking().FirstOrDefault(me => me.MyEntityID == myEntity.MyEntityID); 
+1

AsNoTracking() mejor rendimiento también - google it – Moji

+0

¿Cómo obtener los valores modificados solamente? –

+0

@AwaisMahmood Creo que esto merece una pregunta por separado. –

6

Esto podría ser refinado adicionalmente a lo siguiente:

var originalEntity = context.MyEntities.AsNoTracking() 
     .FirstOrDefault(me => me.MyEntityID == myEntity.MyEntityID); 

El Where en lo anterior, bueno, la respuesta no es necesaria.

0

Me encontré con un problema similar y AsNoTracking no era una opción para mi situación, así que se me ocurrió algo que funciona lo suficientemente bien para mí: primero "clonar" la entidad y luego hacer cambios.

public T Clone<T>(T entity) 
    where T : class, new() { 

    var clone = new T(); 

    var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy) 
    .Where(a => a.CanRead && 
       a.CanWrite && 
       a.GetMethod.IsFinal); 

    foreach (var property in properties) {  
    property.SetValue(clone, property.GetValue(entity)); 
    } 

    return clone; 
} 

y luego compare el clon con el cambiado.

public string GenerateChangeText<T>(T original, T current) 
    where T : class, new() { 

    var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy) 
    .Where(a => a.CanRead && 
       a.CanWrite && 
       a.GetMethod.IsFinal); 

    var changes = string.Empty; 

    foreach (var property in properties) { 

    var originalValue = property.GetValue(original); 
    var currentValue = property.GetValue(current); 

    if (originalValue == null && currentValue == null) continue; 
    if ((originalValue != null && !originalValue.Equals(currentValue)) || 
     (currentValue != null && !currentValue.Equals(originalValue))) { 

     changes += $" changed {property} from {original ?? "NULL"} to {current ?? "NULL"}."; 
    } 
    } 

    return changes; 
} 
0

Existen algunas versiones de Entity Framework en uso.

yo prefiero Código primero y con esa API es fácil como

_context.Entry(Entity).Reload(); 

Docs https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbentityentry.reload(v=vs.103).aspx

Los de más edad de la API tienen un método de actualización en el ObjectContext que puede ayudar en ciertos casos de uso

ObjectContext.Refresh(RefreshMode.StoreWins, Entity); 

Documentos https://msdn.microsoft.com/en-us/library/bb896255(v=vs.110).aspx

0

Esta respuesta se refiere a Entity Framework 6. En EF 6 hay un valor original y valor actual https://msdn.microsoft.com/en-us/library/gg679512(v=vs.113).aspx Después de mirar y no encontrar una buena respuesta, se me ocurrió la siguiente función de prueba y pensé que la publicaría para otros que necesitaran hacer el mismo.

private void test() 
    { 
     // table has a field Description of type varchar(200) 
     WDMDBEntities context = new WDMDBEntities(); 
     var query = context.Brands; 
     List<Brand> records = query.ToList(); 
     if (records.Count > 0) 
     { 
      Brand currentRecord = records[0]; 
      currentRecord.Description = "some new text"; 
      string originalValue = null; 
      switch (context.Entry(currentRecord).State) 
      { 
       case System.Data.Entity.EntityState.Added: 
        originalValue = null; 
        break; 
       case System.Data.Entity.EntityState.Deleted: 
       case System.Data.Entity.EntityState.Detached: 
       case System.Data.Entity.EntityState.Modified: 
       case System.Data.Entity.EntityState.Unchanged: 
        originalValue = context.Entry(currentRecord).Property(u => u.Description).OriginalValue; 
        break; 
      } 
     } 
     context.Dispose(); 
    } 
Cuestiones relacionadas