/// <inheritdoc /> public async Task DeleteAggregateAsync <TIdentity, TAggregate>( TIdentity id, AggregateConfiguration <TIdentity, TAggregate> configuration, long expectedVersion, CancellationToken cancellationToken = default ) where TAggregate : Aggregate <TIdentity, TAggregate> { using var session = await _database.Client.StartSessionAsync(cancellationToken : cancellationToken); var stream = _streamNameResolver.Stream(id, configuration); session.StartTransaction(); try { if (expectedVersion != ExpectedVersion.Any) { var latestEvent = await _events .Find(session, e => e.Stream == stream) .SortByDescending(e => e.EventNumber) .FirstOrDefaultAsync(cancellationToken); if (latestEvent == null) { if (expectedVersion != ExpectedVersion.NoStream) { throw ExpectedVersionValidation.ExpectedStreamToExist(stream, expectedVersion); } } else if (expectedVersion != latestEvent.EventNumber) { throw ExpectedVersionValidation .UnexpectedVersion(stream, expectedVersion, latestEvent.EventNumber); } } await _events.DeleteManyAsync(session, e => e.Stream == stream, null, cancellationToken); await session.CommitTransactionAsync(cancellationToken); } catch (Exception) { // ReSharper disable once MethodSupportsCancellation await session.AbortTransactionAsync(); throw; } }
/// <inheritdoc /> public async Task AppendToStreamAsync <TIdentity, TAggregate>( TIdentity id, AggregateConfiguration <TIdentity, TAggregate> configuration, long expectedVersion, IEnumerable <IPendingEvent> pendingEvents, CancellationToken cancellationToken = default ) where TAggregate : Aggregate <TIdentity, TAggregate> { ExpectedVersionValidation.ValidateExpectedVersion(expectedVersion); var category = configuration.Name; var stream = _streamNameResolver.Stream(id, configuration); using var session = await _events.Database.Client.StartSessionAsync(null, cancellationToken); session.StartTransaction(_transactionOptions); try { var latestEvent = await _events .Find(session, e => e.Stream == stream) .SortByDescending(e => e.EventNumber) .FirstOrDefaultAsync(cancellationToken); var currentVersion = latestEvent?.EventNumber; var startingVersion = ExpectedVersionValidation .StartingVersion(expectedVersion, currentVersion, stream); var recordedEvents = pendingEvents .Select((pendingEvent, index) => RecordedEvent(category, stream, pendingEvent, startingVersion + index) ) .ToArray(); try { await _events.InsertManyAsync(session, recordedEvents, null, cancellationToken); await session.CommitTransactionAsync(cancellationToken); } catch (MongoWriteException ex) { if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) { throw new WrongExpectedVersionException( "Either none or only a subset of the events were previously committed.", expectedVersion, currentVersion ); } throw; } } catch (Exception) { // ReSharper disable once MethodSupportsCancellation await session.AbortTransactionAsync(); throw; } }