protected override sealed async Task PersistModelAsync(PersistEvent @event, TModel model, Graph <TModel> graph, bool create)
        {
            var id         = ModelAnalyzer.GetIdentity(model);
            var streamName = EventStoreCommon.GetStreamName <TModel>(id);

            var eventStoreModel = new EventStoreEventModelData <TModel>()
            {
                Source     = @event.Source,
                SourceType = @event.Source?.GetType().Name,
                Model      = model,
                Graph      = graph
            };

            var data = EventStoreCommon.Serialize(eventStoreModel);

            var eventNumber = await Engine.AppendAsync(@event.ID, @event.Name, streamName, null, create?EventStoreState.NotExisting : EventStoreState.Existing, data);

            if (eventNumber > 0 && eventNumber % SaveStateEvery == 0)
            {
                var thisEventData = (await Engine.ReadBackwardsAsync(streamName, eventNumber, 1, null, null, null))[0];

                var where = ModelAnalyzer.GetIdentityExpression <TModel>(id);

                var eventStates = await Repo.QueryAsync(new EventQueryMany <TModel>(thisEventData.Date, thisEventData.Date, where));

                var eventState = eventStates.Where(x => x.Number == eventNumber).Single();

                await SaveModelStateAsync(id, eventState.Model, eventState.Number);
            }
        }
        protected override sealed async Task DeleteModelAsync(PersistEvent @event, object[] ids)
        {
            foreach (var id in ids)
            {
                var streamName = EventStoreCommon.GetStreamName <TModel>(id);

                var eventNumber = await Engine.TerminateAsync(@event.ID, "Delete", streamName, null, EventStoreState.Existing);

                await SaveModelStateAsync(id, null, eventNumber);
            }
        }
        private async Task <ICollection <EventModel <TModel> > > ReadEventModelsAsync(Query <TModel> query)
        {
            var many = query.Operation == QueryOperation.EventMany || query.Operation == QueryOperation.EventCount;
            var ids  = GetIDs(query);

            var models = new List <EventModel <TModel> >();

            foreach (var id in ids)
            {
                var streamName = EventStoreCommon.GetStreamName <TModel>(id);

                var(modelState, modelEventNumber) = await ReadModelStateAsync(id, query.TemporalOrder, query.TemporalDateFrom, query.TemporalNumberFrom);

                var eventDatas = await Engine.ReadBackwardsAsync(streamName, null, null, modelEventNumber + 1 ?? query.TemporalNumberTo, null, query.TemporalDateTo);

                var items = LoadEventModelsFromEventDatas(eventDatas, modelState, many, query);

                models.AddRange(items);
            }
            return(models);
        }
        private ICollection <TModel> ReadModels(Query <TModel> query)
        {
            var many = query.Operation == QueryOperation.Many || query.Operation == QueryOperation.Count;
            var ids  = GetIDs(query);

            var models = new List <TModel>();

            foreach (var id in ids)
            {
                var streamName = EventStoreCommon.GetStreamName <TModel>(id);

                var(modelState, modelEventNumber) = ReadModelState(id, query.TemporalOrder, query.TemporalDateFrom, query.TemporalNumberFrom);

                var eventDatas = Engine.ReadBackwards(streamName, null, null, modelEventNumber + 1, null, query.TemporalDateTo);

                var items = LoadModelsFromEventDatas(eventDatas, modelState, many, query);

                models.AddRange(items);
            }
            return(models);
        }