public TInternalId this[TNaturalKey naturalKey] { get { using (var connection = new SqlConnection(_sqlServerPersistenceConfiguration.ConnectionString)) { var sql = @"SELECT [AggregateId] FROM [NaturalKeyToAggregateIdMap-{aggName}] WHERE [NaturalKey] = @naturalKey" .Replace("{aggName}", AggregateRootUtils.GetAggregateRootName <TAggregate>()); var command = new SqlCommand(sql, connection); command.Parameters.Add("@naturalKey", SqlDbTypeUtils.GetSqlDbType <TNaturalKey>()).Value = naturalKey; connection.Open(); var result = command.ExecuteScalar(); if (result == null) { throw new KeyNotFoundException($"No entry was found for natural key {naturalKey}"); } return((TInternalId)result); } } }
public IEnumerable <IEvent <TId> > LoadEvents(TId aggregateId, Type aggregateType, bool throwIfNotFound) { using (var connection = new SqlConnection(_sqlServerPersistenceConfiguration.ConnectionString)) { connection.Open(); var sql = @" SELECT [Payload] FROM [dbo].[EventStore-{aggName}] WHERE [AggregateId] = @aggregateId ORDER BY [Version] ASC" .Replace("{aggName}", AggregateRootUtils.GetAggregateRootName(aggregateType)); using (var command = new SqlCommand(sql, connection)) { command.Parameters.Add("@aggregateId", SqlDbTypeUtils.GetSqlDbType <TId>()).Value = aggregateId; using (var reader = command.ExecuteReader()) { if (!reader.HasRows) { if (throwIfNotFound) { throw new AggregateNotFoundException($"Aggregate '{aggregateId}' not found"); } yield break; } while (reader.Read()) { yield return((IEvent <TId>)Deserialize((string)reader[0])); } } } } }
public void Delete(TNaturalKey naturalKey) { using (var connection = new SqlConnection(_sqlServerPersistenceConfiguration.ConnectionString)) { var sql = @"DELETE FROM [NaturalKeyToAggregateIdMap-{aggName}] WHERE [NaturalKey] = @naturalKey" .Replace("{aggName}", AggregateRootUtils.GetAggregateRootName <TAggregate>()); var command = new SqlCommand(sql, connection); command.Parameters.Add("@naturalKey", SqlDbTypeUtils.GetSqlDbType <TNaturalKey>()).Value = naturalKey; connection.Open(); command.ExecuteNonQuery(); } }
public TInternalId GetOrCreateNew(TNaturalKey naturalKey) { using (var connection = new SqlConnection(_sqlServerPersistenceConfiguration.ConnectionString)) { connection.Open(); using (var transaction = connection.BeginTransaction(IsolationLevel.Serializable)) { var sql = @"SELECT [AggregateId] FROM [dbo].[NaturalKeyToAggregateIdMap-{aggName}] WHERE [NaturalKey] = @naturalKey" .Replace("{aggName}", AggregateRootUtils.GetAggregateRootName <TAggregate>()); var command = new SqlCommand(sql, connection, transaction); command.Parameters.Add("@naturalKey", SqlDbTypeUtils.GetSqlDbType <TNaturalKey>()).Value = naturalKey; object result = command.ExecuteScalar(); TInternalId id; if (result != null) { id = (TInternalId)result; } else { sql = @" INSERT INTO [dbo].[NaturalKeyToAggregateIdMap-{aggName}] (NaturalKey, AggregateId) VALUES (@naturalKey, @aggregateID)" .Replace("{aggName}", AggregateRootUtils.GetAggregateRootName <TAggregate>()); id = _aggregateIdCreator.Create(); command = new SqlCommand(sql, connection, transaction); command.Parameters.Add("@naturalKey", SqlDbTypeUtils.GetSqlDbType <TNaturalKey>()).Value = naturalKey; command.Parameters.Add("@aggregateID", SqlDbTypeUtils.GetSqlDbType <TInternalId>()).Value = id; command.ExecuteNonQuery(); } transaction.Commit(); return(id); } } }
public void SaveEvents(TId id, Type aggregateType, IEnumerable <IEvent <TId> > events, int currentVersion, int expectedVersion) { var dataTable = new DataTable(); dataTable.Columns.Add("AggregateId", typeof(TId)); dataTable.Columns.Add("Version", typeof(long)); dataTable.Columns.Add("EventDateTime", typeof(DateTime)); dataTable.Columns.Add("Payload", typeof(string)); foreach (var @event in events) { dataTable.Rows.Add(@event.Id, @event.Version, DateTime.Now, Serialize(@event)); } using (var connection = new SqlConnection(_sqlServerPersistenceConfiguration.ConnectionString)) { connection.Open(); using (var command = new SqlCommand()) { command.Connection = connection; command.CommandType = CommandType.StoredProcedure; command.CommandText = "dbo.usp_Insert{aggName}Events".Replace("{aggName}", AggregateRootUtils.GetAggregateRootName(aggregateType)); command.Parameters.Add("@aggregateId", SqlDbTypeUtils.GetSqlDbType <TId>()).Value = id; command.Parameters.Add("@expectedVersion", SqlDbType.BigInt).Value = expectedVersion; var tableParameter = new SqlParameter(); tableParameter.ParameterName = "@eventsToInsert"; tableParameter.TypeName = "EventStoreType"; tableParameter.SqlDbType = SqlDbType.Structured; tableParameter.Value = dataTable; command.Parameters.Add(tableParameter); try { command.ExecuteNonQuery(); } catch (SqlException ex) when(ex.Number == 51000) { throw new EventStoreConcurrencyException(ex.Message); } } } }
public void DeleteEvents(TId id, Type aggregateType) { using (var connection = new SqlConnection(_sqlServerPersistenceConfiguration.ConnectionString)) { connection.Open(); var getLatestVersionSql = @"DELETE FROM [dbo].[EventStore-{aggName}] WHERE [AggregateId] = @aggregateId".Replace("{aggName}", AggregateRootUtils.GetAggregateRootName(aggregateType)); using (var command = new SqlCommand(getLatestVersionSql, connection)) { command.Parameters.Add("@aggregateId", SqlDbTypeUtils.GetSqlDbType <TId>()).Value = id; command.ExecuteNonQuery(); } } }