static async Task <Concurrency <TSagaData> > GetSagaData <TSagaData>(SynchronizedStorageSession session, string commandText, RuntimeSagaInfo sagaInfo, ParameterAppender appendParameters) where TSagaData : class, IContainSagaData { var sqlSession = session.SqlPersistenceSession(); using (var command = sagaInfo.CreateCommand(sqlSession.Connection)) { command.CommandText = commandText; command.Transaction = sqlSession.Transaction; var dbCommand = command.InnerCommand; appendParameters(dbCommand.CreateParameter, parameter => dbCommand.Parameters.Add(parameter)); // to avoid loading into memory SequentialAccess is required which means each fields needs to be accessed using (var dataReader = await command.ExecuteReaderAsync(CommandBehavior.SingleRow | CommandBehavior.SequentialAccess).ConfigureAwait(false)) { if (!await dataReader.ReadAsync().ConfigureAwait(false)) { return(default);
/// <summary> /// Retrieves a <see cref="IContainSagaData"/> instance. Used when implementing a <see cref="IFindSagas{T}"/>. /// </summary> /// <typeparam name="TSagaData">The <see cref="IContainSagaData"/> type to return.</typeparam> /// <param name="session">Used to provide an extension point and access the current <see cref="DbConnection"/> and <see cref="DbTransaction"/>.</param> /// <param name="context">Used to append a concurrency value that can be verified when the SagaData is persisted.</param> /// <param name="whereClause">The SQL where clause to append to the retrieve saga SQL statement.</param> /// <param name="appendParameters">Used to append <see cref="DbParameter"/>s used in the <paramref name="whereClause"/>.</param> public static Task <TSagaData> GetSagaData <TSagaData>(this SynchronizedStorageSession session, ReadOnlyContextBag context, string whereClause, ParameterAppender appendParameters) where TSagaData : class, IContainSagaData { Guard.AgainstNull(nameof(session), session); Guard.AgainstNull(nameof(context), context); Guard.AgainstNull(nameof(appendParameters), appendParameters); Guard.AgainstNullAndEmpty(nameof(whereClause), whereClause); var writableContextBag = (ContextBag)context; var sqlSession = session.GetSqlStorageSession(); if (sqlSession.InfoCache == null) { throw new Exception("Cannot load saga data because the Sagas feature is disabled in the endpoint."); } return(SagaPersister.GetByWhereClause <TSagaData>(whereClause, session, writableContextBag, appendParameters, sqlSession.InfoCache)); }
static Task <Concurrency <TSagaData> > GetByWhereClause <TSagaData>(string whereClause, SynchronizedStorageSession session, ParameterAppender appendParameters, SagaInfoCache sagaInfoCache) where TSagaData : class, IContainSagaData { var sagaInfo = sagaInfoCache.GetInfo(typeof(TSagaData)); var commandText = sagaInfo.SelectFromCommandBuilder(whereClause); return(GetSagaData <TSagaData>(session, commandText, sagaInfo, appendParameters)); }
internal static async Task <TSagaData> GetByWhereClause <TSagaData>(string whereClause, SynchronizedStorageSession session, ContextBag context, ParameterAppender appendParameters, SagaInfoCache sagaInfoCache) where TSagaData : class, IContainSagaData { var result = await GetByWhereClause <TSagaData>(whereClause, session, appendParameters, sagaInfoCache).ConfigureAwait(false); return(SetConcurrency(result, context)); }
static async Task <Concurrency <TSagaData> > GetSagaData <TSagaData>(SynchronizedStorageSession session, string commandText, RuntimeSagaInfo sagaInfo, ParameterAppender appendParameters) where TSagaData : IContainSagaData { var sqlSession = session.SqlPersistenceSession(); using (var command = sagaInfo.CreateCommand(sqlSession.Connection)) { command.CommandText = commandText; command.Transaction = sqlSession.Transaction; var dbCommand = command.InnerCommand; appendParameters(dbCommand.CreateParameter, parameter => dbCommand.Parameters.Add(parameter)); // to avoid loading into memory SequentialAccess is required which means each fields needs to be accessed using (var dataReader = await command.ExecuteReaderAsync(CommandBehavior.SingleRow | CommandBehavior.SequentialAccess).ConfigureAwait(false)) { if (!await dataReader.ReadAsync().ConfigureAwait(false)) { return(new Concurrency <TSagaData>(default(TSagaData), 0)); } var id = await dataReader.GetGuidAsync(0).ConfigureAwait(false); var sagaTypeVersionString = await dataReader.GetFieldValueAsync <string>(1).ConfigureAwait(false); var sagaTypeVersion = Version.Parse(sagaTypeVersionString); var concurrency = await dataReader.GetFieldValueAsync <int>(2).ConfigureAwait(false); ReadMetadata(dataReader, out var originator, out var originalMessageId); using (var textReader = dataReader.GetTextReader(4)) { var sagaData = sagaInfo.FromString <TSagaData>(textReader, sagaTypeVersion); sagaData.Id = id; sagaData.Originator = originator; sagaData.OriginalMessageId = originalMessageId; return(new Concurrency <TSagaData>(sagaData, concurrency)); } } } }
/// <summary> /// Retrieves a <see cref="IContainSagaData"/> instance. Used when implementing a <see cref="IFindSagas{T}"/>. /// </summary> /// <typeparam name="TSagaData">The <see cref="IContainSagaData"/> type to return.</typeparam> /// <param name="session">Used to provide an extension point and access the current <see cref="DbConnection"/> and <see cref="DbTransaction"/>.</param> /// <param name="context">Used to append a concurrency value that can be verified when the SagaData is persisted.</param> /// <param name="whereClause">The SQL where clause to append to the retrieve saga SQL statement.</param> /// <param name="appendParameters">Used to append <see cref="DbParameter"/>s used in the <paramref name="whereClause"/>.</param> public static Task <TSagaData> GetSagaData <TSagaData>(this SynchronizedStorageSession session, ReadOnlyContextBag context, string whereClause, ParameterAppender appendParameters) where TSagaData : class, IContainSagaData { Guard.AgainstNull(nameof(session), session); Guard.AgainstNull(nameof(context), context); Guard.AgainstNull(nameof(appendParameters), appendParameters); Guard.AgainstNullAndEmpty(nameof(whereClause), whereClause); var writableContextBag = (ContextBag)context; var sqlSession = session.GetSqlStorageSession(); return(SagaPersister.GetByWhereClause <TSagaData>(whereClause, session, writableContextBag, appendParameters, sqlSession.InfoCache)); }
/// <summary> /// Retrieves a <see cref="IContainSagaData"/> instance. Used when implementing a <see cref="IFindSagas{T}"/>. /// </summary> /// <typeparam name="TSagaData">The <see cref="IContainSagaData"/> type to return.</typeparam> /// <param name="session">Used to provide an extension point and access the current <see cref="DbConnection"/> and <see cref="DbTransaction"/>.</param> /// <param name="context">Used to append a concurrency value that can be verified when the SagaData is persisted.</param> /// <param name="whereClause">The SQL where clause to append to the retrieve saga SQL statement.</param> /// <param name="appendParameters">Used to append <see cref="DbParameter"/>s used in the <paramref name="whereClause"/>.</param> public static Task <TSagaData> GetSagaData <TSagaData>(this SynchronizedStorageSession session, ReadOnlyContextBag context, string whereClause, ParameterAppender appendParameters) where TSagaData : IContainSagaData { Guard.AgainstNull(nameof(session), session); Guard.AgainstNull(nameof(context), context); Guard.AgainstNull(nameof(appendParameters), appendParameters); Guard.AgainstNullAndEmpty(nameof(whereClause), whereClause); var writableContextBag = (ContextBag)context; var sqlSession = session.GetSqlStorageSession(); var sagaInfoCache = sqlSession.InfoCache; if (sagaInfoCache == null) { throw new Exception($"{nameof(GetSagaData)} can only be executed when Sagas have been enabled on the endpoint."); } return(SagaPersister.GetByWhereClause <TSagaData>(whereClause, session, writableContextBag, appendParameters, sagaInfoCache)); }