2011-11-15 16 views

risposta

13

È possibile accedere attraverso ObjectStateEntry

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

originalValues ​​è il tipo DbDataRecord. Come convertirlo in tipo di entità? – JatSing

+0

@Sun non ha tipi di entità. È necessario eseguire il cast dei valori sul tipo appropriato. es. 'var name = (stringa) originalValues ​​[" Name "];' – Eranga

27

@Eranga risposta è obsoleto per EF 5. Per qualche ragione, EF 5 non funziona bene quando ottenere valori originali utilizzando una dichiarazione come questa:

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

la mia soluzione di lavoro utilizza AsNoTracking() metodo dal DbSet, come nell'esempio qui sotto:

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

AsNoTracking() prestazioni migliori pure - google it – Moji

+0

Come ottenere solo i valori modificati ?? –

+0

@AwaisMahmood Penso che questo meriti una domanda a parte. –

6

Questo potrebbe essere raffinato ulteriormente di seguito:

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

Il Where in quanto sopra, bene, risposta non è necessaria.

0

Mi sono imbattuto in un problema simile e AsNoTracking non era un'opzione per la mia situazione, quindi mi è venuto in mente qualcosa che funzioni abbastanza bene per me: prima "clonare" l'entità, quindi apportare delle modifiche.

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

e quindi confrontare il clone con il modificato.

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

Esistono alcune versioni di Entity Framework in uso.

Io stesso preferisco Codice Prima e con tale API è facile come

_context.Entry(Entity).Reload(); 

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

Gli API hanno un metodo di aggiornamento sul ObjectContext che può aiutare in alcuni casi d'uso

ObjectContext.Refresh(RefreshMode.StoreWins, Entity); 

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

0

Questa risposta si riferisce a Entity Framework 6. In EF 6 c'è un valore originale e il valore corrente https://msdn.microsoft.com/en-us/library/gg679512(v=vs.113).aspx Dopo aver cercato e non aver trovato una buona risposta, mi è venuta in mente la seguente funzione di test e ho pensato di postarla per gli altri che dovevano fare il stesso.

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(); 
    } 
Problemi correlati