2012-09-06 9 views
9

Ho un piccolo problema con l'aggiornamento delle entità se l'entità viene modificata all'esterno di DbContext (è un'entità indipendente). Se allego l'entità modificata, lo stato non viene modificato.Come aggiornare le entità che sono modificate al di fuori di DbContext?

Il mio codice è simile al seguente:

var specificationToSave = GetSpecificationFromTmpStore(userSessionGuid); 
using (var context = DataContextFactory.GetDataContext()) 
{ 
    // this works for update, if I change the values inside the context while debugging 
    // but it breaks with new entities 
    context.Specifications.Attach(specificationToSave); 

    // this works for insert new entities, modified entities will be saved as new entities 
    context.Specifications.Add((specificationToSave);) 
    context.SaveChanges(); 
} 

so NHibernate ed è il metodo SaveOrUpdate. NHibernate decide a causa dei valori se sta aggiornando o inserendo le entità.

Qual è la procedura migliore per farlo con EF 4.xe con le entità che sono modificate al di fuori di DbContext? Come posso dire all'EF che questa entità è in stato modificato?

risposta

21

Inoltre, è necessario comunicare a EF che l'entità è modified, dopo averla allegata.

context.Entry(specificationToSave).State = EntityState.Modified; 

In alternativa, è possibile apportare le modifiche all'entità dopo aver riattaccato esso, per esempio vedi MVC3 with EF 4.1 and EntityState.Modified

Modifica

È possibile utilizzare farmaci generici con DbSet - sia di classe, o un metodo - come segue:

public void Update<TEntity>(TEntity entity) 
    { 
     DbContext.Set<TEntity>().Attach(entity); 
     DbContext.Entry(entity).State = EntityState.Modified; 
     DbContext.SaveChanges(); 
    } 

Edit: Per l'aggiornamento del genitore distaccato/Bambino Grafici

Per l'aggiornamento di relazioni parent/child semplici/superficiali in cui l'efficienza e le prestazioni non sono importanti, semplicemente eliminando tutto il vecchio Iren e reinserire i nuovi è una soluzione facile (anche se brutta).

Tuttavia, per uno scenario più efficiente è necessario che attraversiamo il grafico, rileviamo le modifiche, quindi aggiungiamo di recente inserito, aggiorniamo esistenti, ignoriamo invariato ed eliminiamo gli elementi rimossi dallo Context.

Slauma mostra un ottimo esempio of this here.

Si potrebbe voler usare GraphDiff, che può fare tutto questo lavoro gamba per te!

+1

Grazie mille :-) Questo è quello che stavo cercando. Il secondo modo è il migliore, ma in questo caso non è possibile. Quindi devo aggiornare direttamente lo stato di DbEntityEntry. Non è una soluzione molto bella ma funziona. –

+0

È vero, se è necessario impostare lo stato di ogni entità correlata di "specificationToSave". per esempio se ho un elenco di elementi modificati nel mio 'specificationToSave'. Spero davvero che ci sia una soluzione semplice per farlo ... –

+0

@ Jürgen genitore: gli scenari figlio richiedono una considerazione speciale, poiché potrebbe essere necessario aggiungere, eliminare o aggiornare i bambini. FWIW In genere faccio solo un hash sui bambini per vedere se qualcuno è cambiato, e se lo ha, quindi per eliminare tutti gli esistenti e inserire di nuovo tutti i bambini. Ma questo sono solo io che sono pigro. – StuartLC