/// <summary>
        /// Queries the saga index for an instance with the given <paramref name="sagaDataType"/> with a
        /// a property named <paramref name="propertyName"/> and the value <paramref name="propertyValue"/>
        /// </summary>
        public async Task<ISagaData> Find(Type sagaDataType, string propertyName, object propertyValue)
        {
            if (sagaDataType == null) throw new ArgumentNullException(nameof(sagaDataType));
            if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));
            if (propertyValue == null) throw new ArgumentNullException(nameof(propertyValue));

            using (var connection = await _connectionProvider.GetConnection())
            {
                using (var command = connection.CreateCommand())
                {
                    if (propertyName.Equals(IdPropertyName, StringComparison.OrdinalIgnoreCase))
                    {
                        command.CommandText = $@"SELECT TOP 1 [data] FROM {_dataTableName.QualifiedName} WHERE [id] = @value";
                    }
                    else
                    {
                        command.CommandText =
                            $@"
SELECT TOP 1 [saga].[data] AS 'data' FROM {_dataTableName.QualifiedName} [saga] 
    JOIN {_indexTableName.QualifiedName} [index] ON [saga].[id] = [index].[saga_id] 
WHERE [index].[saga_type] = @saga_type
    AND [index].[key] = @key 
    AND [index].[value] = @value
";

                        var sagaTypeName = GetSagaTypeName(sagaDataType);

                        command.Parameters.Add("key", SqlDbType.NVarChar, propertyName.Length).Value = propertyName;
                        command.Parameters.Add("saga_type", SqlDbType.NVarChar, sagaTypeName.Length).Value = sagaTypeName;
                    }

                    var correlationPropertyValue = GetCorrelationPropertyValue(propertyValue);

                    command.Parameters.Add("value", SqlDbType.NVarChar, correlationPropertyValue.Length).Value = correlationPropertyValue;

                    using (var reader = await command.ExecuteReaderAsync())
                    {
                        if (!await reader.ReadAsync()) return null;

                        var value = GetData(reader);

                        try
                        {
                            var sagaData = (ISagaData)ObjectSerializer.DeserializeFromString(value);

                            if (!sagaDataType.IsInstanceOfType(sagaData))
                            {
                                return null;
                            }

                            return sagaData;
                        }
                        catch (Exception exception)
                        {
                            throw new RebusApplicationException(exception, $"An error occurred while attempting to deserialize '{value}' into a {sagaDataType}");
                        }
                    }
                }
            }
        }
Beispiel #2
0
        internal static T Get <T>(this IMessageContext messageContext, string key) where T : class
        {
            if (messageContext.Headers.ContainsKey(key) == false)
            {
                return(null);
            }

            var messageString = messageContext.Headers[key];

            var data = m_objectSerializer.DeserializeFromString(messageString);

            if (data is T dataTyped)
            {
                return(dataTyped);
            }

            return(null);
        }