Sto usando EF Core 2.1
e sto cercando di aggiornare più entità in una volta utilizzando Tasks
(TPL):
public async Task UpdateAttendance(IEnumerable<MyEvents> events)
{
try
{
var tasks = events.Select(async entity =>
{
await Task.Run(() => Context.Entry(entity).Property(x => x.Attendance).IsModified = true);
await Context.SaveChangesAsync();
});
await Task.WhenAll(tasks);
}
catch (Exception ex)
{
throw new Exception(ex.Message ?? ex.InnerException.Message);
}
}
Ma questo lancia l'errore qui sotto.
Una seconda operazione è iniziata in questo contesto prima che una precedente operazione fosse completata. Non è garantito che tutti i membri di istanza siano thread-safe.
Startup.cs
services.AddScoped<IMyRepository, MyRepository>();
Come posso affrontare questo?
Non puoi farlo. EF Core (come prima EF 6) non è thread-safe.
Bisogna attendere un compito prima di iniziare quello successivo
var tasks = events.Select(async entity =>
{
await Task.Run(() => Context.Entry(entity).Property(x => x.Attendance).IsModified = true);
await Context.SaveChangesAsync();
});
await Task.WhenAll(tasks);
Qui stai avviando più attività in parallelo e aspettandole. Dovrai passarci sopra
foreach(var entity in events)
{
Context.Entry(entity).Property(x => x.Attendance).IsModified = true;
});
await Context.SaveChangesAsync();
Non sono proprio sicuro del motivo per cui vuoi salvarlo evento per evento (quindi, l'esempio è stato modificato per fare tutti i flag modificati prima di chiamare SaveChangesAsync()
), in quanto piuttosto inefficiente. Ha più senso aggiornare tutte le proprietà, quindi eseguire SaveChanges alla fine, poiché EF Core salverà tutte le entità modificate / monitorate quando salvi le modifiche. È anche più facile eseguire un rollback quando qualcosa va storto (l'operazione all'interno di SaveChangesAsync avviene nell'ambito di una transazione)