public void When_the_EventStoreDbContext_seeds_it_calls_the_specified_seed_action_if_it_has_been_set() { var numberOfEventsToSeed = Any.PositiveInt(100); var methodName = MethodBase.GetCurrentMethod().Name; var eventStoreInitializer1 = new EventStoreDatabaseInitializer<EventStoreDbContext>(); eventStoreInitializer1.OnSeed = ctx => { var aggregateId = Guid.NewGuid(); Enumerable.Range(20, numberOfEventsToSeed) .ForEach(i => ctx.Events.Add(new StorableEvent { AggregateId = aggregateId, SequenceNumber = i, Body = "test event!", StreamName = GetType().Name, Type = methodName })); }; using (var eventStore = new EventStoreDbContext()) { eventStoreInitializer1.InitializeDatabase(eventStore); eventStore.Events.Count().Should().Be(numberOfEventsToSeed); } }
public void RelatedEvents_handles_circular_references() { var relatedId1 = Any.Guid(); var relatedId2 = Any.Guid(); var relatedId3 = Any.Guid(); Console.WriteLine(new { relatedId1, relatedId2, relatedId3, }.ToLogString()); using (var db = new EventStoreDbContext()) { db.Events.Add(new StorableEvent { AggregateId = relatedId1, SequenceNumber = 1, Body = new { relatedId2 }.ToJson(), Timestamp = Clock.Now(), StreamName = "one", Type = "Event" }); db.Events.Add(new StorableEvent { AggregateId = relatedId2, SequenceNumber = 1, Body = new { relatedId3 }.ToJson(), Timestamp = Clock.Now(), StreamName = "two", Type = "Event" }); db.Events.Add(new StorableEvent { AggregateId = relatedId3, SequenceNumber = 1, Body = new { relatedId1 }.ToJson(), Timestamp = Clock.Now(), StreamName = "three", Type = "Event" }); db.SaveChanges(); } // assert using (var db = new EventStoreDbContext()) { var events = db.Events.RelatedEvents(relatedId1).ToArray(); events.Count().Should().Be(3); events.Should().Contain(e => e.AggregateId == relatedId1); events.Should().Contain(e => e.AggregateId == relatedId2); events.Should().Contain(e => e.AggregateId == relatedId3); } }
private EventStore(IDomainEventDispatcher domainEventDispatcher) { _eventStoreContext = new EventStoreDbContext(new DbContextOptionsBuilder <EventStoreDbContext>() .UseInMemoryDatabase(databaseName: "EventStore") .EnableSensitiveDataLogging() .Options); _domainEventDispatcher = domainEventDispatcher; }
public void event_store_type_and_id_are_indexed() { using (var context = new EventStoreDbContext()) { var result = context.QueryDynamic(@"SELECT * FROM sys.indexes WHERE name='IX_Id_and_Type' AND object_id = OBJECT_ID('eventstore.events')").Single(); result.Should().NotBeEmpty(); } }
protected override async Task DeleteEventsFromEventStore(Guid aggregateId) { using (var db = new EventStoreDbContext()) { db.Database.ExecuteSqlCommand(string.Format("DELETE FROM EventStore.Events WHERE AggregateId = '{0}'", aggregateId)); await db.SaveChangesAsync(); } }
private List <Event> ExtractEventsFromChangeTracker(EventStoreDbContext ctx) { return(ctx.ChangeTracker .Entries() .Where(e => e.State != EntityState.Deleted && e.State != EntityState.Detached && e.Entity is Event) .Select(e => (Event)e.Entity) .WhereNotNull() .ToList()); }
public void event_store_etag_is_nullable() { using (var context = new EventStoreDbContext()) { var result = context.QueryDynamic(@"SELECT * FROM sys.columns WHERE name='ETag' AND object_id = OBJECT_ID('eventstore.events')").Single(); bool is_nullable = result.Single().is_nullable; is_nullable.Should().BeTrue(); } }
public IntegrationEventLogService(DbConnection dbConnection) { _dbConnection = dbConnection ?? throw new ArgumentNullException("dbConnection"); _eventStoreContext = new EventStoreDbContext( new DbContextOptionsBuilder <EventStoreDbContext>() .UseMySql(_dbConnection) .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)) .Options); }
private EventStore(IProjectorHost projectorHost, IDomainEventDispatcher domainEventDispatcher) { _eventStoreContext = new EventStoreDbContext(new DbContextOptionsBuilder <EventStoreDbContext>() .UseInMemoryDatabase(databaseName: "EventStore") .EnableSensitiveDataLogging() .Options); (_projectorHost, _domainEventDispatcher) = (projectorHost, domainEventDispatcher); }
private void CleanDatabases() { using (var ctx = new EventStoreDbContext(GetDbOptions())) { ctx.RemoveRange(ctx.Set <Event>()); ctx.RemoveRange(ctx.Set <Snapshot>()); ctx.SaveChanges(); } }
public void Init() { EventStoreDbContext.NameOrConnectionString = @"Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=False; Initial Catalog=ItsCqrsTestsEventStore"; using (var eventStore = new EventStoreDbContext()) { new EventStoreDatabaseInitializer <EventStoreDbContext>().InitializeDatabase(eventStore); } }
public void Dispose() { using (var context = new EventStoreDbContext(this.connectionString)) { if (context.Database.Exists()) { context.Database.Delete(); } } }
public void EventStore_polling_continues_even_if_connection_gets_closed_during_replay() { Events.Write(3); var scheduler = new TestScheduler(); var projector = new Projector <Order.ItemAdded>(() => new ReadModels1DbContext()) { OnUpdate = (work, e) => { } }; var statusReports = new List <ReadModelCatchupStatus>(); var catchup = CreateReadModelCatchup <ReadModels1DbContext>(projector); DbConnection dbConnection = new SqlConnection(); catchup.CreateEventStoreDbContext = () => { var context = new EventStoreDbContext(); dbConnection = ((IObjectContextAdapter)context).ObjectContext.Connection; return(context); }; using (catchup) { catchup.Progress .ForEachAsync(s => { Console.WriteLine(s); if (!s.IsStartOfBatch && !s.IsEndOfBatch) { Console.WriteLine("closing the connection"); // close the connection dbConnection.Close(); } statusReports.Add(s); }); catchup.PollEventStore(TimeSpan.FromSeconds(5), scheduler); // Advance to trigger the first catchup scheduler.AdvanceBy(TimeSpan.FromSeconds(5).Ticks); // Trigger an empty batch replay scheduler.AdvanceBy(TimeSpan.FromSeconds(5).Ticks); Events.Write(2); // Advance to trigger the polling catchup scheduler.AdvanceBy(TimeSpan.FromSeconds(9).Ticks); statusReports.Count(s => s.IsStartOfBatch) .Should() .Be(3); } }
private async Task <AggregateState> GetRehydratedAggregateStateAsync( object aggregateId, Type aggregateType, EventStoreDbContext externalCtx = null) { List <IDomainEvent> events = new List <IDomainEvent>(); #if NETSTANDARD2_0 events = await GetAllEventsByAggregateId(aggregateType, aggregateId) .ToList().ConfigureAwait(false); #elif NETSTANDARD2_1 await foreach (var @event in GetAllEventsByAggregateId(aggregateType, aggregateId)) { events.Add(@event); } #endif if (externalCtx != null) { var eventsInChangeTracker = ExtractEventsFromChangeTracker(externalCtx).Select(GetRehydratedEventFromDbEvent); events = events.Concat(eventsInChangeTracker).OrderBy(s => s.Sequence).ToList(); } Snapshot snapshot = null; using (var ctx = new EventStoreDbContext(_dbContextOptions, _archiveBehavior)) { var hashedAggregateId = aggregateId.ToJson(true).GetHashCode(); snapshot = await ctx.Set <Snapshot>() .Where(t => t.AggregateType == aggregateType.AssemblyQualifiedName && t.HashedAggregateId == hashedAggregateId) .FirstOrDefaultAsync().ConfigureAwait(false); } PropertyInfo stateProp = aggregateType.GetAllProperties().FirstOrDefault(p => p.PropertyType.IsSubclassOf(typeof(AggregateState))); FieldInfo stateField = aggregateType.GetAllFields().FirstOrDefault(f => f.FieldType.IsSubclassOf(typeof(AggregateState))); Type stateType = stateProp?.PropertyType ?? stateField?.FieldType; AggregateState state = null; if (stateType != null) { if (snapshot != null) { state = snapshot.SnapshotData.FromJson(stateType) as AggregateState; } else { state = stateType.CreateInstance() as AggregateState; } } else { throw new InvalidOperationException("EFEventStore.GetRehydratedAggregateAsync() : Cannot find property/field that manage state for aggregate" + $" type {aggregateType.FullName}. State should be a property or a field of the aggregate"); } state.ApplyRange(events); return(state); }
public InProcessEventStreamReaderTestsFixture() { var options = new DbContextOptionsBuilder <EventStoreDbContext>() .UseSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=EventStreamReadersIntegrationTests;Integrated Security=False") .Options; using (var dbContext = new EventStoreDbContext(options)) { DatabaseSeeder.Seed(dbContext); } }
public MySqlEventStore( IdentityAccessDbContext context ) { _context = context ?? throw new ArgumentNullException(nameof(context)); _eventStoreDbContext = new EventStoreDbContext( new DbContextOptionsBuilder <EventStoreDbContext>() .UseMySql(_context.Database.GetDbConnection()) .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)) .Options); }
private async Task ManageSnapshotBehavior( IDomainEvent @event, EventStoreDbContext ctx, int hashedAggregateId) { bool IsSnaphostEnabled() { return(_snapshotBehaviorProvider != null && _archiveBehavior != SnapshotEventsArchiveBehavior.Disabled); } if (@event.AggregateId != null && @event.AggregateType != null) { var evtType = @event.GetType(); if (IsSnaphostEnabled()) { var behavior = _snapshotBehaviorProvider !.GetBehaviorForEventType(evtType); if (behavior?.IsSnapshotNeeded(@event) == true) { var aggState = await GetRehydratedAggregateStateAsync(@event.AggregateId, @event.AggregateType, ctx) .ConfigureAwait(false); var eventsToArchive = behavior.GenerateSnapshot(aggState); if (eventsToArchive?.Any() == true) { if (aggState != null) { var previousSnapshot = await ctx .Set <Snapshot>() .FirstOrDefaultAsync(s => s.HashedAggregateId == hashedAggregateId && s.AggregateType == @event.AggregateType.AssemblyQualifiedName) .ConfigureAwait(false); if (previousSnapshot != null) { ctx.Remove(previousSnapshot); } ctx.Add(new Snapshot { AggregateType = @event.AggregateType.AssemblyQualifiedName, HashedAggregateId = hashedAggregateId, SnapshotBehaviorType = behavior.GetType().AssemblyQualifiedName, SnapshotTime = DateTime.Now, SnapshotData = aggState.ToJson(new AggregateStateSerialisationContract()) }); } await StoreArchiveEventsAsync(eventsToArchive, ctx).ConfigureAwait(false); } } } } }
public MySqlEventStore(DbConnection dbConnection, IEventPublisher publisher) { _dbConnection = dbConnection ?? throw new ArgumentNullException("dbConnection"); _eventStoreContext = new EventStoreDbContext( new DbContextOptionsBuilder <EventStoreDbContext>() .UseMySql(_dbConnection) .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)) .Options); _publisher = publisher ?? throw new ArgumentNullException(nameof(publisher)); }
public EventStoreDbTest() { Logging.Configure(); SetConnectionStrings(); Command <Order> .AuthorizeDefault = (order, command) => true; Command <CustomerAccount> .AuthorizeDefault = (order, command) => true; lock (lockObj) { if (databasesInitialized) { return; } // TODO: (EventStoreDbTest) figure out a db cleanup story //#if !DEBUG // new EventStoreDbContext().Database.Delete(); // new OtherEventStoreDbContext().Database.Delete(); // new ReadModelDbContext().Database.Delete(); // new ReadModels1DbContext().Database.Delete(); // new ReadModels2DbContext().Database.Delete(); // new CommandSchedulerDbContext().Database.Delete(); //#endif using (var eventStore = new EventStoreDbContext()) { new EventStoreDatabaseInitializer <EventStoreDbContext>().InitializeDatabase(eventStore); } using (var db = new CommandSchedulerDbContext()) { new CommandSchedulerDatabaseInitializer().InitializeDatabase(db); } using (var eventStore = new OtherEventStoreDbContext()) { new EventStoreDatabaseInitializer <OtherEventStoreDbContext>().InitializeDatabase(eventStore); } using (var db = new ReadModelDbContext()) { new ReadModelDatabaseInitializer <ReadModelDbContext>().InitializeDatabase(db); } using (var db = new ReadModels1DbContext()) { new ReadModelDatabaseInitializer <ReadModels1DbContext>().InitializeDatabase(db); } using (var db = new ReadModels2DbContext()) { new ReadModelDatabaseInitializer <ReadModels2DbContext>().InitializeDatabase(db); } databasesInitialized = true; } }
public static async Task SaveToEventStore <TAggregate>(this TAggregate aggregate) where TAggregate : EventSourcedAggregate { using (var db = new EventStoreDbContext()) { foreach (var e in aggregate.EventHistory.OfType <IEvent <TAggregate> >()) { var storableEvent = e.ToStorableEvent(); db.Events.Add(storableEvent); } await db.SaveChangesAsync(); } }
public IAsyncEnumerable <IDomainEvent> GetAllEventsByEventType(Type eventType) { using (var ctx = new EventStoreDbContext(_dbContextOptions)) { var dbEvents = ctx .Set <Event>() .AsNoTracking() .Where(c => c.EventType == eventType.AssemblyQualifiedName) .ToList(); return(dbEvents.Select(GetRehydratedEventFromDbEvent).ToAsyncEnumerable()); } }
private async Task StoreArchiveEventsAsync(IEnumerable <IDomainEvent> archiveEvents, EventStoreDbContext externalCtx) { switch (_archiveBehavior) { case SnapshotEventsArchiveBehavior.StoreToNewTable: using (var ctx = new EventStoreDbContext(_dbContextOptions)) { ctx.AddRange(archiveEvents.Select(GetArchiveEventFromIDomainEvent).ToList()); await ctx.SaveChangesAsync().ConfigureAwait(false); } break; case SnapshotEventsArchiveBehavior.StoreToNewDatabase: if (_archiveBehaviorDbContextOptions != null) { using (var ctx = new ArchiveEventStoreDbContext(_archiveBehaviorDbContextOptions)) { ctx.AddRange( archiveEvents.Select(GetArchiveEventFromIDomainEvent)); await ctx.SaveChangesAsync().ConfigureAwait(false); } } else { throw new InvalidOperationException("EFEventStore.StoreDomainEventAsync() : Snapshot will be created and event to archive cannot be saved because DbContextOptions for archive database weren't provided during configuration on Bootstrapper. Either specify DbContextOptions for event's archive database or change archive behavior"); } break; } var eventsInContext = externalCtx .ChangeTracker .Entries() .Where(e => e.State != EntityState.Detached && e.State != EntityState.Deleted) .Select(e => e.Entity as Event) .WhereNotNull() .Where(e => archiveEvents.Any(ev => ev.Id == e !.Id)) .ToList(); if (eventsInContext.Count > 0) { eventsInContext.DoForEach(e => externalCtx.Entry(e).State = EntityState.Detached); } using (var ctx = new EventStoreDbContext(_dbContextOptions)) { var archiveEventsIds = archiveEvents.Select(e => e.Id).ToList(); var events = await ctx.Set <Event>().Where(e => archiveEventsIds.Contains(e.Id)).ToListAsync().ConfigureAwait(false); if (events.Count > 0) { ctx.RemoveRange(events); await ctx.SaveChangesAsync().ConfigureAwait(false); } } }
internal static void CreateDatabase(DatabaseType databaseType) { var options = databaseType == DatabaseType.SQLite ? new DbContextOptionsBuilder <EventStoreDbContext>().UseSqlite(GetConnectionString_SQLite()).Options : new DbContextOptionsBuilder <EventStoreDbContext>().UseSqlServer(GetConnectionString_SQLServer()).Options; using (var ctx = new EventStoreDbContext(options)) { ctx.Database.EnsureDeleted(); ctx.Database.EnsureCreated(); } }
private static void CreateDb() { Console.WriteLine("Creating Db..."); using (var context = new EventStoreDbContext(FixedConnectionstring)) { context.Database.Create(); Console.WriteLine("Db created"); Console.WriteLine("Adding subscriptions..."); // promo AddSubscriptions(context); } }
protected override void SaveEventsDirectly(params object[] events) { using (var db = new EventStoreDbContext()) { events .Select(e => e.IfTypeIs <StorableEvent>() .Else(() => e.IfTypeIs <IEvent>() .Then(ee => ee.ToStorableEvent())) .ElseDefault()) .ForEach(e => { db.Events.Add(e); }); db.SaveChanges(); } }
public IAsyncEnumerable <T> GetAllEventsByEventType <T>() where T : class, IDomainEvent { using (var ctx = new EventStoreDbContext(_dbContextOptions)) { var dbEvents = ctx .Set <Event>() .AsNoTracking() .Where(c => c.EventType == typeof(T).AssemblyQualifiedName) .ToList(); return(dbEvents.Select(e => GetRehydratedEventFromDbEvent(e) as T).WhereNotNull().ToAsyncEnumerable()); } }
static public void Initialize() { var options = new DbContextOptionsBuilder <EventStoreDbContext>() .UseSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=EventStreamReactiveObservablesExample;Integrated Security=False") .Options; using (var dbContext = new EventStoreDbContext(options)) { dbContext.Database.EnsureDeleted(); dbContext.Database.EnsureCreated(); DatabaseSeeder.Seed(dbContext); } }
public IAsyncEnumerable <IDomainEvent> GetAllEventsByAggregateId(Type aggregateType, object aggregateId) { using (var ctx = new EventStoreDbContext(_dbContextOptions)) { var dbEvents = ctx .Set <Event>() .AsNoTracking() .Where(c => c.AggregateType == aggregateType.AssemblyQualifiedName && c.AggregateIdType == aggregateId.GetType().AssemblyQualifiedName && c.HashedAggregateId == aggregateId.ToJson(true).GetHashCode()) .ToList(); return(dbEvents.Select(GetRehydratedEventFromDbEvent).ToAsyncEnumerable()); } }
public void SeedFromFile_can_be_used_to_seed_the_event_store_from_config() { eventStoreInitializer.OnSeed = ctx => { var file = Settings.GetFile(f => f.Name == "Events.json"); ctx.SeedFromFile(file); }; using (var eventStore = new EventStoreDbContext()) { eventStoreInitializer.InitializeDatabase(eventStore); eventStore.Events.Count().Should().Be(8); } }
public async IAsyncEnumerable <IDomainEvent> GetAllEventsByAggregateType(Type aggregateType) { using (var ctx = new EventStoreDbContext(_dbContextOptions)) { var dbEvents = ctx .Set <Event>() .AsNoTracking() .Where(c => c.AggregateType == aggregateType.AssemblyQualifiedName) .AsAsyncEnumerable(); await foreach (var @event in dbEvents) { yield return(GetRehydratedEventFromDbEvent(@event)); } } }
public void SeedFromFile_can_be_used_to_seed_the_event_store_from_config() { var eventStoreInitializer1 = new EventStoreDatabaseInitializer<EventStoreDbContext>(); eventStoreInitializer1.OnSeed = ctx => { var file = Settings.GetFile(f => f.Name == "Events.json"); ctx.SeedFromFile(file); }; using (var eventStore = new EventStoreDbContext()) { eventStoreInitializer1.InitializeDatabase(eventStore); eventStore.Events.Count().Should().Be(8); } }
public static AppDbContext WithDefaults() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase($"{Guid.NewGuid()}") .Options; var context = new EventStoreDbContext(options); var dateTime = new MachineDateTime(); var eventStore = new EventStore(context, dateTime, new TestCorrelationIdAccessor(Guid.NewGuid())); var aggregateSet = new AggregateSet(context, dateTime); var appDbContext = new AppDbContext(eventStore, aggregateSet); DbInitializer.Initialize(appDbContext, ConfigurationFactory.Create()); appDbContext.SaveChangesAsync(default).GetAwaiter().GetResult();
public async Task AzureSqlDatabase_can_be_configured_using_a_migration() { var databaseSettings = Settings.Get<AzureSqlDatabaseSettings>(); databaseSettings.DatabaseName = "ItsCqrsMigrationsTest"; var connectionString = databaseSettings.BuildConnectionString(); using (var context = new EventStoreDbContext(connectionString)) { new EventStoreDatabaseInitializer<EventStoreDbContext>().InitializeDatabase(context); var migrator = new AzureSqlDbMigrator( "S0", "10 GB", new Version("0.0.42.1")); context.EnsureDatabaseIsUpToDate(migrator); context.OpenConnection() .GetAppliedMigrationVersions() .Should() .Contain("0.0.42.1"); } }
public void AzureSqlDatabase_EventStore_can_be_configured_using_a_migration() { var databaseSettings = Settings.Get<AzureSqlDatabaseSettings>(); databaseSettings.DatabaseName = "ItsCqrsMigrationsTestEventStore"; var connectionString = databaseSettings.BuildConnectionString(); using (var context = new EventStoreDbContext(connectionString)) { new EventStoreDatabaseInitializer<EventStoreDbContext>().InitializeDatabase(context); var migrator = new AzureSqlDbMigrator( serviceObjective: "S0", edition: "standard", maxSize: "500 MB", migrationVersion: new Version("0.0.42.1")); context.EnsureDatabaseIsUpToDate(migrator); context.OpenConnection() .GetLatestAppliedMigrationVersions() .Should() .Contain(v => v.MigrationVersion.ToString() == "0.0.42.1"); } }
public async Task RelatedEvents_can_return_several_nonintersecting_graphs_at_once() { var graph1Id1 = Any.Guid(); var graph1Id2 = Any.Guid(); var graph2Id1 = Any.Guid(); var graph2Id2 = Any.Guid(); Console.WriteLine(new { graph1Id1, graph1Id2, graph2Id1, graph2Id2 }.ToLogString()); using (var db = new EventStoreDbContext()) { db.Events.Add(new StorableEvent { AggregateId = graph1Id1, SequenceNumber = 1, Body = new { graph1Id2 }.ToJson(), Timestamp = Clock.Now(), StreamName = "one", Type = "Event" }); db.Events.Add(new StorableEvent { AggregateId = graph1Id2, SequenceNumber = 1, Body = new { }.ToJson(), Timestamp = Clock.Now(), StreamName = "one", Type = "Event" }); db.Events.Add(new StorableEvent { AggregateId = graph2Id1, SequenceNumber = 1, Body = new { graph2Id2 }.ToJson(), Timestamp = Clock.Now(), StreamName = "two", Type = "Event" }); db.Events.Add(new StorableEvent { AggregateId = graph2Id2, SequenceNumber = 1, Body = new { }.ToJson(), Timestamp = Clock.Now(), StreamName = "two", Type = "Event" }); db.SaveChanges(); } // assert using (var db = new EventStoreDbContext()) { var events = (await db.Events.RelatedEvents(graph1Id1, graph2Id1)).ToArray(); events.Count().Should().Be(4); events.Should().Contain(e => e.AggregateId == graph1Id1); events.Should().Contain(e => e.AggregateId == graph1Id2); events.Should().Contain(e => e.AggregateId == graph2Id1); events.Should().Contain(e => e.AggregateId == graph2Id2); } }
public async Task RelatedEvents_handles_circular_references() { var relatedId1 = Any.Guid(); var relatedId2 = Any.Guid(); var relatedId3 = Any.Guid(); Console.WriteLine(new { relatedId1, relatedId2, relatedId3, }.ToLogString()); using (var db = new EventStoreDbContext()) { db.Events.Add(new StorableEvent { AggregateId = relatedId1, SequenceNumber = 1, Body = new { relatedId2 }.ToJson(), Timestamp = Clock.Now(), StreamName = "one", Type = "Event" }); db.Events.Add(new StorableEvent { AggregateId = relatedId2, SequenceNumber = 1, Body = new { relatedId3 }.ToJson(), Timestamp = Clock.Now(), StreamName = "two", Type = "Event" }); db.Events.Add(new StorableEvent { AggregateId = relatedId3, SequenceNumber = 1, Body = new { relatedId1 }.ToJson(), Timestamp = Clock.Now(), StreamName = "three", Type = "Event" }); db.SaveChanges(); } // assert using (var db = new EventStoreDbContext()) { var events = (await db.Events.RelatedEvents(relatedId1)).ToArray(); events.Count().Should().Be(3); events.Should().Contain(e => e.AggregateId == relatedId1); events.Should().Contain(e => e.AggregateId == relatedId2); events.Should().Contain(e => e.AggregateId == relatedId3); } }
public async Task RelatedEvents_returns_all_events_in_related_aggregates() { // arrange var relatedId1 = Any.Guid(); var relatedId2 = Any.Guid(); var relatedId3 = Any.Guid(); var relatedId4 = Any.Guid(); var unrelatedId = Any.Guid(); Console.WriteLine(new { relatedId1, relatedId2, relatedId3, relatedId4, unrelatedId }.ToLogString()); using (var db = new EventStoreDbContext()) { Enumerable.Range(1, 20).ForEach(i => db.Events.Add(new StorableEvent { AggregateId = relatedId1, SequenceNumber = i, Body = new { relatedId2 }.ToJson(), Timestamp = Clock.Now(), StreamName = "one", Type = "Event" + i.ToString() })); Enumerable.Range(1, 20).ForEach(i => db.Events.Add(new StorableEvent { AggregateId = relatedId2, SequenceNumber = i, Body = new { relatedId3 }.ToJson(), Timestamp = Clock.Now(), StreamName = "two", Type = "Event" + i.ToString() })); Enumerable.Range(1, 20).ForEach(i => db.Events.Add(new StorableEvent { AggregateId = relatedId3, SequenceNumber = i, Body = new { relatedId4 }.ToJson(), Timestamp = Clock.Now(), StreamName = "three", Type = "Event" + i.ToString() })); Enumerable.Range(1, 20).ForEach(i => db.Events.Add(new StorableEvent { AggregateId = relatedId4, SequenceNumber = i, Body = new { }.ToJson(), Timestamp = Clock.Now(), StreamName = "three", Type = "Event" + i.ToString() })); Enumerable.Range(1, 20).ForEach(i => db.Events.Add(new StorableEvent { AggregateId = unrelatedId, SequenceNumber = i, Body = new { }.ToJson(), Timestamp = Clock.Now(), StreamName = "three", Type = "Event" + i.ToString() })); db.SaveChanges(); } using (var db = new EventStoreDbContext()) { //act var events = (await db.Events.RelatedEvents(relatedId1)).ToArray(); // assert events.Count().Should().Be(80); events.Should().Contain(e => e.AggregateId == relatedId1); events.Should().Contain(e => e.AggregateId == relatedId2); events.Should().Contain(e => e.AggregateId == relatedId3); events.Should().Contain(e => e.AggregateId == relatedId4); events.Should().NotContain(e => e.AggregateId == unrelatedId); } }