Il modo standard sarebbe utilizzare la concorrenza ottimistica.
Dite, avete un semplice ente con un campo intero Counter
che si desidera incrementare o decrementare:
public class SomeEntity
{
public int SomeEntityId { get; set; }
public int Counter { get; set; }
}
Si potrebbe segnare l'Counter
poi come un token concorrenza. API Ottima è:
modelBuilder.Entity<SomeEntity>()
.Property(s => s.Counter)
.IsConcurrencyToken();
Quindi è possibile incrementare o decrementare il Counter
per esempio in questo modo:
public void IncDecCounter(int someEntityId, bool dec)
{
using (var context = new MyContext())
{
var someEntity = context.SomeEntities.Find(someEntityId);
if (someEntity != null)
{
bool saveFailed;
do
{
saveFailed = false;
if (dec)
--someEntity.Counter;
else
++someEntity.Counter;
try
{
context.SaveChanges();
}
catch (DbUpdateConcurrencyException e)
{
saveFailed = true;
e.Entries.Single().Reload();
}
} while (saveFailed);
}
}
}
SaveChanges
fallirà DbUpdateConcurrencyException
se il valore della Counter
quando l'entità è stata caricata (con Find
in questo esempio, potrebbe essere qualsiasi altra query) si differenzia dal valore di Counter
nel database quando l'istruzione UPDATE viene eseguita nel database, il che significherebbe che lo Counter
è stato modificato da un altro utente i Nel frattempo Tecnicamente ciò è ottenuto da una clausola estesa WHERE
dell'istruzione UPDATE generata che tenta di filtrare non solo dall'Id ma anche dal vecchio valore di Counter
, in pratica qualcosa come: WHERE SomeEntityId = someEntityId AND Counter = oldCounterWhenTheEntityHasBeenLoaded
.
Il blocco catch
ricarica l'entità con il valore corrente Counter
dal database e il ciclo successivo tenta di incrementare o decrementare nuovamente il valore ricaricato finché non riesce senza violazione della concorrenza.
Grazie. ;-) Speriamo che sia abbastanza veloce (-; – NickD
@Slauma, dove viene chiamato questo codice? 'ModelBuilder.Entity() .Property (s => s.Counter) .IsConcurrencyToken();' esegue il tuo soluzione ancora valida in EF6/6.1? E ultima cosa :) - Come ti avvicineresti a questo? Non ho ricevuto una risposta EF-Wise ... http://stackoverflow.com/questions/35825947/creating-object-counters-in-entity-framework-and-sql-server –
ilans