private async Task Save <T>( List <IDomainEvent> domainEvents, string operationId, Guid?correlationId, string contributor, CancellationToken cancellationToken) where T : class, IEventSourced { var envelopes = new List <Envelope <IDomainEvent> >( from domainEvent in domainEvents let messageId = Guid.NewGuid() select new Envelope <IDomainEvent>(messageId, domainEvent, operationId, correlationId, contributor)); var batch = new TableBatchOperation(); foreach (Envelope <IDomainEvent> envelope in envelopes) { batch.Insert(PersistentEvent.Create(typeof(T), envelope, _serializer)); batch.Insert(PendingEvent.Create(typeof(T), envelope, _serializer)); } Guid sourceId = domainEvents.First().SourceId; if (correlationId.HasValue) { batch.Insert(Correlation.Create(typeof(T), sourceId, correlationId.Value)); } try { await _eventTable.ExecuteBatch(batch, cancellationToken).ConfigureAwait(false); } catch (StorageException exception) when(correlationId.HasValue) { string filter = Correlation.GetFilter(typeof(T), sourceId, correlationId.Value); var query = new TableQuery <Correlation> { FilterString = filter }; if (await _eventTable.Any(query, cancellationToken).ConfigureAwait(false)) { throw new DuplicateCorrelationException( typeof(T), sourceId, correlationId.Value, exception); } throw; } }
private async Task InsertEventsAndCorrelation <T>( List <Envelope> envelopes, Guid?correlationId, CancellationToken cancellationToken) where T : class, IEventSourced { var batch = new TableBatchOperation(); var firstEvent = (IDomainEvent)envelopes.First().Message; Guid sourceId = firstEvent.SourceId; foreach (Envelope envelope in envelopes) { batch.Insert(EventTableEntity.FromEnvelope <T>(envelope, _serializer)); } if (correlationId.HasValue) { batch.Insert(CorrelationTableEntity.Create(typeof(T), sourceId, correlationId.Value)); } try { await _eventTable.ExecuteBatchAsync(batch, cancellationToken).ConfigureAwait(false); } catch (StorageException exception) when(correlationId.HasValue) { string filter = CorrelationTableEntity.GetFilter(typeof(T), sourceId, correlationId.Value); var query = new TableQuery <CorrelationTableEntity>().Where(filter); if (await _eventTable.Any(query, cancellationToken)) { throw new DuplicateCorrelationException( typeof(T), sourceId, correlationId.Value, exception); } throw; } }