internal static async Task <int> SaveChangesAsync( this DbContext context, RefreshConflict refreshMode, int retryCount = 3) { if (retryCount <= 0) { throw new ArgumentOutOfRangeException(nameof(retryCount)); } return(await context.SaveChangesAsync( async conflicts => await Task.WhenAll(conflicts.Select(async tracking => await tracking.RefreshAsync(refreshMode))), retryCount)); }
internal static async Task <int> SaveChangesAsync( this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy) => await context.SaveChangesAsync( async conflicts => await Task.WhenAll(conflicts.Select(async tracking => await tracking.RefreshAsync(refreshMode))), retryStrategy);
internal static async Task <EntityEntry> RefreshAsync(this EntityEntry tracking, RefreshConflict refreshMode) { switch (refreshMode) { case RefreshConflict.StoreWins: { await tracking.ReloadAsync(); break; } case RefreshConflict.ClientWins: { PropertyValues databaseValues = await tracking.GetDatabaseValuesAsync(); if (databaseValues == null) { tracking.State = EntityState.Detached; } else { tracking.OriginalValues.SetValues(databaseValues); } break; } case RefreshConflict.MergeClientAndStore: { PropertyValues databaseValues = await tracking.GetDatabaseValuesAsync(); if (databaseValues == null) { tracking.State = EntityState.Detached; } else { PropertyValues originalValues = tracking.OriginalValues.Clone(); tracking.OriginalValues.SetValues(databaseValues); databaseValues.Properties .Where(property => !object.Equals(originalValues[property.Name], databaseValues[property.Name])) .ForEach(property => tracking.Property(property.Name).IsModified = false); } break; } } return(tracking); }