Exemple #1
0
        private ConcurrencyResolutionResult HandleEntryGeneric <TEntity>(PropertyValues originalValues, PropertyValues currentValues, PropertyValues proposedValues)
        {
            var handlers = _serviceProvider
                           .GetServices <IConcurrencyErrorHandler <TEntity> >();

            ConcurrencyLogMessages.ConcurrencyErrorHandlersExecuting(_logger);

            var result = ConcurrencyResolutionResult.Unhandled;

            foreach (var handler in handlers)
            {
                ConcurrencyLogMessages.ConcurrencyErrorHandlerExecuting(_logger, handler);

                result = handler.HandleConcurrencyError(originalValues, currentValues, proposedValues);
                if (result.IsHandled)
                {
                    ConcurrencyLogMessages.EntityEntryHandledByHandler(_logger, handler);
                    break;
                }

                ConcurrencyLogMessages.EntityEntryNotHandledByHandler(_logger, handler);
            }

            return(result);
        }
Exemple #2
0
        // For the record, don't even bother trying to Unit Test this. DbUpdateConcurrencyException is not mockable.
        // Layers upon layers of non-mockable dependencies, plus polymorphism abuse, just for extra fun
        // (E.G. if you try and use an IEntityType that isn't EntityType, you get an exception)
        public async Task HandleExceptionAsync(DbUpdateConcurrencyException exception, CancellationToken cancellationToken)
        {
            ConcurrencyLogMessages.ConcurrencyExceptionHandling(_logger, exception);

            foreach (var entry in exception.Entries)
            {
                ConcurrencyLogMessages.EntityEntryHandling(_logger, entry);

                var tEntity        = entry.Entity.GetType();
                var originalValues = entry.OriginalValues;
                var currentValues  = await entry.GetDatabaseValuesAsync(cancellationToken);

                var proposedValues = entry.CurrentValues;

                if (HandleEntry(tEntity, originalValues, currentValues, proposedValues).IsUnhandled)
                {
                    ConcurrencyLogMessages.ConcurrencyExceptionNotHandled(_logger, exception);
                    throw new InvalidOperationException($"Concurrency exception for entity type {entry.Entity.GetType()} was unhandled", exception);
                }

                ConcurrencyLogMessages.EntityEntryHandled(_logger);
                entry.OriginalValues.SetValues(currentValues);
            }

            ConcurrencyLogMessages.ConcurrencyExceptionHandled(_logger);
        }