예제 #1
0
        public static int SubmitSaveChanges(this DbContext dbContext,
                                            bool acceptAllChangesOnSuccess = true)
        {
            dbContext.NotNull(nameof(dbContext));

            CheckDisposed(dbContext);

            var dependencies = dbContext.GetService <IDbContextDependencies>();

            dependencies.UpdateLogger.SaveChangesStarting(dbContext);

            TryDetectChanges(dbContext);

            try
            {
                var entitiesSaved = dependencies.StateManager.SaveChanges(acceptAllChangesOnSuccess);

                dependencies.UpdateLogger.SaveChangesCompleted(dbContext, entitiesSaved);

                return(entitiesSaved);
            }
            catch (DbUpdateConcurrencyException exception)
            {
                dependencies.UpdateLogger.OptimisticConcurrencyException(dbContext, exception);

                throw;
            }
            catch (Exception exception)
            {
                dependencies.UpdateLogger.SaveChangesFailed(dbContext, exception);

                throw;
            }
        }
예제 #2
0
        public static void ConcurrentUpdates <TEntity>(this DbContext dbContext,
                                                       DbUpdateConcurrencyException exception, Func <TEntity, bool> predicate, string updatePropertyName = null)
            where TEntity : class
        {
            dbContext.NotNull(nameof(dbContext));
            exception.NotNull(nameof(exception));

            foreach (var entry in exception.Entries)
            {
                if (entry.Entity is TEntity)
                {
                    foreach (var property in entry.Metadata.GetProperties())
                    {
                        var dbEntity      = dbContext.Set <TEntity>().AsNoTracking().Single(predicate);
                        var dbEntityEntry = dbContext.Entry(dbEntity);

                        //var proposedValue = entry.Property(property.Name).CurrentValue;
                        //var originalValue = entry.Property(property.Name).OriginalValue;
                        //var databaseValue = dbEntityEntry.Property(property.Name).CurrentValue;

                        // 如果要更新的属性名不为空且等于当前属性,或要更新的属性名为空,则并发更新此属性
                        if ((updatePropertyName.IsNotEmpty() && property.Name == updatePropertyName) ||
                            updatePropertyName.IsEmpty())
                        {
                            // Update original values to
                            entry.Property(property.Name).OriginalValue = dbEntityEntry.Property(property.Name).CurrentValue;

                            if (updatePropertyName.IsNotEmpty())
                            {
                                break; // 如果只更新当前属性,则跳出属性遍历
                            }
                        }
                    }
                }
                else
                {
                    throw new NotSupportedException("Don't know how to handle concurrency conflicts for " + entry.Metadata.Name);
                }
            }

            dbContext.SaveChanges();
        }
예제 #3
0
        public static async Task <int> SubmitSaveChangesAsync(this DbContext dbContext,
                                                              bool acceptAllChangesOnSuccess = true, CancellationToken cancellationToken = default)
        {
            dbContext.NotNull(nameof(dbContext));

            CheckDisposed(dbContext);

            var dependencies = dbContext.GetService <IDbContextDependencies>();

            dependencies.UpdateLogger.SaveChangesStarting(dbContext);

            TryDetectChanges(dbContext);

            try
            {
                var entitiesSaved = await dependencies.StateManager
                                    .SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken)
                                    .ConfigureAwait();

                dependencies.UpdateLogger.SaveChangesCompleted(dbContext, entitiesSaved);

                return(entitiesSaved);
            }
            catch (DbUpdateConcurrencyException exception)
            {
                dependencies.UpdateLogger.OptimisticConcurrencyException(dbContext, exception);

                throw;
            }
            catch (Exception exception)
            {
                dependencies.UpdateLogger.SaveChangesFailed(dbContext, exception);

                throw;
            }
        }