lucabriguglia / OpenCQRS

.NET Standard framework to create simple and clean design. Advanced features for DDD, CQRS and Event Sourcing.
Apache License 2.0
3 stars 115 forks source link

About load Events #111

Open xiongdashan opened 4 years ago

xiongdashan commented 4 years ago

I have a question: In "AggregateRoot.cs", the value is assigned to it by looping through all events. If there are a lot of Events,will it cause performance issues?

Load all events

https://github.com/lucabriguglia/Kledex/blob/467c4a4af12d733173a8b1751dff3001618a3e9d/src/Kledex.Store.EF/StoreProvider.cs#L54

public async Task<IEnumerable<IDomainEvent>> GetEventsAsync(Guid aggregateId)
        {
            var result = new List<DomainEvent>();

            using (var dbContext = _dbContextFactory.CreateDbContext())
            {
                var events = await dbContext.Events
                    .Where(x => x.AggregateId == aggregateId)
                    .OrderBy(x => x.Sequence)
                    .ToListAsync();

                foreach (var @event in events)
                {
                    var domainEvent = JsonConvert.DeserializeObject(@event.Data, Type.GetType(@event.Type));
                    result.Add((DomainEvent)domainEvent);
                }
            }

            return result;
        }

Foreach all events and assgin value:

https://github.com/lucabriguglia/Kledex/blob/467c4a4af12d733173a8b1751dff3001618a3e9d/src/Kledex/Domain/AggregateRoot.cs#L30

        public void LoadsFromHistory(IEnumerable<IDomainEvent> events)
        {
            var domainEvents = events as IDomainEvent[] ?? events.ToArray();

            foreach (var @event in domainEvents)
            {
                ApplyEvent(@event);
            }
        }
lucabriguglia commented 4 years ago

Potentially yes if there are a lot of events, and I mean a lot. One way to mitigate the potential issue is to create snapshots and retrieve only events from a certain point in time. I have already created an issue to address this and I hope to have the time to implement the feature at some point.

xiongdashan commented 4 years ago

Thanks for your answer, could load aggregateroot after the event, update the changed data and save it again, and then load only the most recent update in the loadhistory method? That is, the first entry in the event table is the complete latest data. It only needs to take top 1 each time.

lucabriguglia commented 4 years ago

Yes, it could be possible by saving a snapshot of the whole aggregate for each event.

xiongdashan commented 4 years ago

Create a new table or use the current event table? Which is right?

lucabriguglia commented 4 years ago

Same table or container, just an extra property for the event (e.g. Snapshot)