public void PlaceHolder() { var sagaId = Guid.NewGuid(); Expression <Func <TestType, bool> > filter = x => x.Id == sagaId || x.Completed && x.Name != "Kebabsvarv"; var result = WhereStatementHelper.GetWhereStatementAndParametersFromExpression(filter); }
async Task <IEnumerable <Guid> > IQuerySagaRepository <TSaga> .Find(ISagaQuery <TSaga> query) { using (var connection = new SqlConnection(_connectionString)) { var tableName = GetTableName <TSaga>(); var(whereStatement, parameters) = WhereStatementHelper.GetWhereStatementAndParametersFromExpression(query.FilterExpression); return ((await connection.QueryAsync <Guid>($"SELECT CorrelationId FROM {tableName} WITH (UPDLOCK, ROWLOCK) {whereStatement}", parameters).ConfigureAwait(false)).ToList()); } }
public async Task SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) using (var connection = new SqlConnection(_connectionString)) { try { var tableName = GetTableName <T>(); var(whereStatement, parameters) = WhereStatementHelper.GetWhereStatementAndParametersFromExpression(context.Query.FilterExpression); List <TSaga> instances = (await connection.QueryAsync <TSaga>($"SELECT * FROM {tableName} WITH (UPDLOCK, ROWLOCK) {whereStatement}", parameters).ConfigureAwait(false)).ToList(); if (!instances.Any()) { var missingSagaPipe = new MissingPipe <T>(connection, tableName, next, InsertSagaInstance); await policy.Missing(context, missingSagaPipe); } else { foreach (var instance in instances) { await SendToInstance(context, connection, policy, instance, tableName, next).ConfigureAwait(false); } } transaction.Complete(); } catch (SagaException sex) { if (Log.IsErrorEnabled) { Log.Error($"SAGA:{TypeMetadataCache<TSaga>.ShortName} Exception {TypeMetadataCache<T>.ShortName}", sex); } throw; } catch (Exception ex) { if (Log.IsErrorEnabled) { Log.Error($"SAGA:{TypeMetadataCache<TSaga>.ShortName} Exception {TypeMetadataCache<T>.ShortName}", ex); } throw new SagaException(ex.Message, typeof(TSaga), typeof(T), Guid.Empty, ex); } } }
public void GetWhereStatementAndParametersFromExpression_HandlesSingleValues() { // Arrange var sagaId = NewId.NextGuid(); Expression <Func <SimpleSaga, bool> > filter = x => x.CorrelationId == sagaId; // Act var(whereStatement, dynamicParameters) = WhereStatementHelper.GetWhereStatementAndParametersFromExpression(filter); // Assert Assert.That(whereStatement, Is.EqualTo("WHERE CorrelationId = @value0")); var sagaIdParameter = dynamicParameters.Get <Guid>("value0"); Assert.That(sagaIdParameter, Is.EqualTo(sagaId)); }
public async Task <IEnumerable <T> > QueryAsync <T>(Expression <Func <T, bool> > filterExpression, CancellationToken cancellationToken) where T : class, ISaga { var tableName = GetTableName <T>(); var(whereStatement, parameters) = WhereStatementHelper.GetWhereStatementAndParametersFromExpression(filterExpression); await _inUse.WaitAsync(cancellationToken).ConfigureAwait(false); try { return(await _connection.QueryAsync <T>($"SELECT * FROM {tableName} WITH (UPDLOCK, ROWLOCK) {whereStatement}", parameters, _transaction) .ConfigureAwait(false)); } finally { _inUse.Release(); } }
public void GetWhereStatementAndParametersFromExpression_HandlesMultipleValues() { // Arrange var sagaId = NewId.NextGuid(); Expression <Func <SimpleSaga, bool> > filter = x => x.CorrelationId == sagaId && x.Completed && x.CorrelateBySomething == "Kebabsvarv"; // Act var(whereStatement, dynamicParameters) = WhereStatementHelper.GetWhereStatementAndParametersFromExpression(filter); // Assert Assert.That(whereStatement, Is.EqualTo("WHERE CorrelationId = @value0 AND Completed = @value1 AND CorrelateBySomething = @value2")); var sagaIdParameter = dynamicParameters.Get <Guid>("value0"); Assert.That(sagaIdParameter, Is.EqualTo(sagaId)); var completedParameter = dynamicParameters.Get <object>("value1"); Assert.That(completedParameter, Is.True); var correlateBySomethingParameter = dynamicParameters.Get <string>("value2"); Assert.That(correlateBySomethingParameter, Is.EqualTo("Kebabsvarv")); }
public async Task SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { var tableName = GetTableName <T>(); var(whereStatement, parameters) = WhereStatementHelper.GetWhereStatementAndParametersFromExpression(context.Query.FilterExpression); List <Guid> correlationIds = null; using (var connection = new SqlConnection(_connectionString)) { correlationIds = (await connection.QueryAsync <Guid>( $"SELECT CorrelationId FROM {tableName} {whereStatement}", parameters).ConfigureAwait(false)).ToList(); } using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) using (var connection = new SqlConnection(_connectionString)) { try { var missingCorrelationIds = new List <Guid>(); foreach (var correlationId in correlationIds) { var instance = await connection.QuerySingleOrDefaultAsync <TSaga>( $"SELECT * FROM {tableName} WITH (UPDLOCK, ROWLOCK) where CorrelationId = @correlationId", new { correlationId }).ConfigureAwait(false); if (instance != null) { await SendToInstance(context, connection, policy, instance, tableName, next).ConfigureAwait(false); } else { missingCorrelationIds.Add(correlationId); } } // If no sagas are found or all are missing if (correlationIds.Count == missingCorrelationIds.Count) { var missingSagaPipe = new MissingPipe <T>(connection, tableName, next, InsertSagaInstance); await policy.Missing(context, missingSagaPipe).ConfigureAwait(false); } transaction.Complete(); } catch (SagaException sex) { if (Log.IsErrorEnabled) { Log.Error($"SAGA:{TypeMetadataCache<TSaga>.ShortName} Exception {TypeMetadataCache<T>.ShortName}", sex); } throw; } catch (Exception ex) { if (Log.IsErrorEnabled) { Log.Error($"SAGA:{TypeMetadataCache<TSaga>.ShortName} Exception {TypeMetadataCache<T>.ShortName}", ex); } throw new SagaException(ex.Message, typeof(TSaga), typeof(T), Guid.Empty, ex); } } }