public override async Task UpdateAsync( IReadOnlyCollection <ReadModelUpdate> readModelUpdates, IReadModelContext readModelContext, Func <IReadModelContext, IReadOnlyCollection <IDomainEvent>, ReadModelEnvelope <TReadModel>, CancellationToken, Task <ReadModelEnvelope <TReadModel> > > updateReadModel, CancellationToken cancellationToken) { foreach (var readModelUpdate in readModelUpdates) { IMssqlReadModel mssqlReadModel; var readModelNameLowerCased = typeof(TReadModel).Name.ToLowerInvariant(); var readModelEnvelope = await GetAsync(readModelUpdate.ReadModelId, cancellationToken).ConfigureAwait(false); var readModel = readModelEnvelope.ReadModel; var isNew = readModel == null; if (readModel == null) { readModel = await _readModelFactory.CreateAsync(readModelUpdate.ReadModelId, cancellationToken).ConfigureAwait(false); mssqlReadModel = readModel as IMssqlReadModel; if (mssqlReadModel != null) { mssqlReadModel.AggregateId = readModelUpdate.ReadModelId; mssqlReadModel.CreateTime = readModelUpdate.DomainEvents.First().Timestamp; } readModelEnvelope = ReadModelEnvelope <TReadModel> .With(readModelUpdate.ReadModelId, readModel); } readModelEnvelope = await updateReadModel( readModelContext, readModelUpdate.DomainEvents, readModelEnvelope, cancellationToken) .ConfigureAwait(false); mssqlReadModel = readModel as IMssqlReadModel; if (mssqlReadModel != null) { mssqlReadModel.UpdatedTime = DateTimeOffset.Now; mssqlReadModel.LastAggregateSequenceNumber = (int)readModelEnvelope.Version.GetValueOrDefault(); } else { SetVersion(readModel, (int?)readModelEnvelope.Version); } var sql = isNew ? _readModelSqlGenerator.CreateInsertSql <TReadModel>() : _readModelSqlGenerator.CreateUpdateSql <TReadModel>(); await _connection.ExecuteAsync( Label.Named("mssql-store-read-model", readModelNameLowerCased), cancellationToken, sql, readModel).ConfigureAwait(false); } }
public override async Task UpdateAsync( IReadOnlyCollection <ReadModelUpdate> readModelUpdates, IReadModelContext readModelContext, Func <IReadModelContext, IReadOnlyCollection <IDomainEvent>, ReadModelEnvelope <TReadModel>, CancellationToken, Task <ReadModelEnvelope <TReadModel> > > updateReadModel, CancellationToken cancellationToken) { foreach (var readModelUpdate in readModelUpdates) { var readModelNameLowerCased = typeof(TReadModel).Name.ToLowerInvariant(); var readModelEnvelope = await GetAsync(readModelUpdate.ReadModelId, cancellationToken).ConfigureAwait(false); var readModel = readModelEnvelope.ReadModel; var isNew = readModel == null; if (readModel == null) { readModel = await _readModelFactory.CreateAsync(readModelUpdate.ReadModelId, cancellationToken) .ConfigureAwait(false); readModelEnvelope = ReadModelEnvelope <TReadModel> .With(readModelUpdate.ReadModelId, readModel); } readModelEnvelope = await updateReadModel( readModelContext, readModelUpdate.DomainEvents, readModelEnvelope, cancellationToken) .ConfigureAwait(false); SetVersion(readModel, (int?)readModelEnvelope.Version); SetIdentity(readModel, readModelEnvelope.ReadModelId); var sql = isNew ? _readModelSqlGenerator.CreateInsertSql <TReadModel>() : _readModelSqlGenerator.CreateUpdateSql <TReadModel>(); await _connection.ExecuteAsync( Label.Named("sql-store-read-model", readModelNameLowerCased), cancellationToken, sql, readModel).ConfigureAwait(false); } }
private async Task UpdateReadModelAsync( IReadModelContextFactory readModelContextFactory, Func <IReadModelContext, IReadOnlyCollection <IDomainEvent>, ReadModelEnvelope <TReadModel>, CancellationToken, Task <ReadModelUpdateResult <TReadModel> > > updateReadModel, CancellationToken cancellationToken, ReadModelUpdate readModelUpdate) { IMssqlReadModel mssqlReadModel; var readModelId = readModelUpdate.ReadModelId; var readModelEnvelope = await GetAsync(readModelId, cancellationToken).ConfigureAwait(false); var readModel = readModelEnvelope.ReadModel; var isNew = readModel == null; if (readModel == null) { readModel = await _readModelFactory.CreateAsync(readModelId, cancellationToken) .ConfigureAwait(false); mssqlReadModel = readModel as IMssqlReadModel; if (mssqlReadModel != null) { mssqlReadModel.AggregateId = readModelId; mssqlReadModel.CreateTime = readModelUpdate.DomainEvents.First().Timestamp; } readModelEnvelope = ReadModelEnvelope <TReadModel> .With(readModelUpdate.ReadModelId, readModel); } var readModelContext = readModelContextFactory.Create(readModelId, isNew); var originalVersion = readModelEnvelope.Version; var readModelUpdateResult = await updateReadModel( readModelContext, readModelUpdate.DomainEvents, readModelEnvelope, cancellationToken) .ConfigureAwait(false); if (!readModelUpdateResult.IsModified) { return; } readModelEnvelope = readModelUpdateResult.Envelope; if (readModelContext.IsMarkedForDeletion) { await DeleteAsync(readModelId, cancellationToken).ConfigureAwait(false); return; } mssqlReadModel = readModel as IMssqlReadModel; if (mssqlReadModel != null) { mssqlReadModel.UpdatedTime = DateTimeOffset.Now; mssqlReadModel.LastAggregateSequenceNumber = (int)readModelEnvelope.Version.GetValueOrDefault(); } else { SetVersion(readModel, (int?)readModelEnvelope.Version); } var sql = isNew ? _readModelSqlGenerator.CreateInsertSql <TReadModel>() : _readModelSqlGenerator.CreateUpdateSql <TReadModel>(); var dynamicParameters = new DynamicParameters(readModel); if (originalVersion.HasValue) { dynamicParameters.Add("_PREVIOUS_VERSION", (int)originalVersion.Value); } var rowsAffected = await _connection.ExecuteAsync( Label.Named("mssql-store-read-model", ReadModelNameLowerCase), cancellationToken, sql, dynamicParameters).ConfigureAwait(false); if (rowsAffected != 1) { throw new OptimisticConcurrencyException( $"Read model '{readModelEnvelope.ReadModelId}' updated by another"); } Log.Verbose(() => $"Updated MSSQL read model {typeof(TReadModel).PrettyPrint()} with ID '{readModelId}' to version '{readModelEnvelope.Version}'"); }
private async Task UpdateReadModelAsync( IReadModelContext readModelContext, Func <IReadModelContext, IReadOnlyCollection <IDomainEvent>, ReadModelEnvelope <TReadModel>, CancellationToken, Task <ReadModelEnvelope <TReadModel> > > updateReadModel, CancellationToken cancellationToken, ReadModelUpdate readModelUpdate) { var readModelNameLowerCased = typeof(TReadModel).Name.ToLowerInvariant(); var readModelEnvelope = await GetAsync(readModelUpdate.ReadModelId, cancellationToken).ConfigureAwait(false); var readModel = readModelEnvelope.ReadModel; var isNew = readModel == null; if (readModel == null) { readModel = await _readModelFactory.CreateAsync(readModelUpdate.ReadModelId, cancellationToken).ConfigureAwait(false); readModelEnvelope = ReadModelEnvelope <TReadModel> .With(readModelUpdate.ReadModelId, readModel); } var originalVersion = readModelEnvelope.Version; readModelEnvelope = await updateReadModel( readModelContext, readModelUpdate.DomainEvents, readModelEnvelope, cancellationToken) .ConfigureAwait(false); if (readModelContext.IsMarkedForDeletion) { await DeleteAsync(readModelUpdate.ReadModelId, cancellationToken); return; } SetVersion(readModel, (int?)readModelEnvelope.Version); SetIdentity(readModel, readModelEnvelope.ReadModelId); var sql = isNew ? _readModelSqlGenerator.CreateInsertSql <TReadModel>() : _readModelSqlGenerator.CreateUpdateSql <TReadModel>(); var dynamicParameters = new DynamicParameters(readModel); if (originalVersion.HasValue) { dynamicParameters.Add("_PREVIOUS_VERSION", (int)originalVersion.Value); } var rowsAffected = await _connection.ExecuteAsync( Label.Named("sql-store-read-model", readModelNameLowerCased), cancellationToken, sql, dynamicParameters) .ConfigureAwait(false); if (rowsAffected != 1) { throw new OptimisticConcurrencyException( $"Read model '{readModelEnvelope.ReadModelId}' updated by another"); } Log.Verbose(() => $"Updated SQL read model {typeof(TReadModel).PrettyPrint()} with ID '{readModelUpdate.ReadModelId}' to version '{readModelEnvelope.Version}'"); }