public async Task Delete_deletes_Memento_entity()
        {
            // Arrange
            var sourceId = Guid.NewGuid();
            var memento  = new FakeUserMemento();

            var sut = new SqlMementoStore(
                () => new MementoStoreDbContext(_dbContextOptions),
                new JsonMessageSerializer());

            await sut.Save <FakeUser>(sourceId, memento, default);

            // Act
            await sut.Delete <FakeUser>(sourceId, default);

            // Assert
            using (var db = new MementoStoreDbContext(_dbContextOptions))
            {
                bool actual = await db
                              .Mementoes
                              .Where(m => m.AggregateId == sourceId)
                              .AnyAsync();

                actual.Should().BeFalse();
            }
        }
        public async Task Save_inserts_Memento_entity_correctly()
        {
            // Arrange
            var sourceId = Guid.NewGuid();
            var memento  = new FakeUserMemento();

            var serializer = new JsonMessageSerializer();

            var sut = new SqlMementoStore(
                () => new MementoStoreDbContext(_dbContextOptions),
                serializer);

            // Act
            await sut.Save <FakeUser>(sourceId, memento, default);

            // Assert
            using (var db = new MementoStoreDbContext(_dbContextOptions))
            {
                Memento actual = await db
                                 .Mementoes
                                 .AsNoTracking()
                                 .Where(m => m.AggregateId == sourceId)
                                 .SingleOrDefaultAsync();

                actual.Should().NotBeNull();
                object restored = serializer.Deserialize(actual.MementoJson);
                restored.Should().BeOfType <FakeUserMemento>();
                restored.ShouldBeEquivalentTo(memento);
            }
        }
        private async Task SaveMemento(
            Guid sourceId,
            IMemento memento,
            CancellationToken cancellationToken)
        {
            using (MementoStoreDbContext context = _dbContextFactory.Invoke())
            {
                Memento entity = await context
                                 .Mementoes
                                 .Where(m => m.AggregateId == sourceId)
                                 .SingleOrDefaultAsync(cancellationToken)
                                 .ConfigureAwait(false);

                if (entity == null)
                {
                    entity = new Memento {
                        AggregateId = sourceId
                    };
                    context.Mementoes.Add(entity);
                }

                entity.MementoJson = _serializer.Serialize(memento);

                await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
            }
        }
        public void model_has_Memento_entity()
        {
            var         sut    = new MementoStoreDbContext(_dbContextOptions);
            IEntityType actual = sut.Model.FindEntityType(typeof(Memento));

            actual.Should().NotBeNull();
        }
        public void Memento_entity_has_index_with_AggregateId()
        {
            var         sut    = new MementoStoreDbContext(_dbContextOptions);
            IEntityType entity = sut.Model.FindEntityType(typeof(Memento));
            IIndex      actual = entity.FindIndex(entity.FindProperty("AggregateId"));

            actual.Should().NotBeNull();
            actual.IsUnique.Should().BeTrue();
        }
        public async Task Save_updates_Memento_entity_if_already_exists()
        {
            // Arrange
            var sourceId = Guid.NewGuid();

            var oldMemento = new FakeUserMemento();
            var newMemento = new FakeUserMemento();

            var serializer = new JsonMessageSerializer();

            long sequence = 0;

            using (var db = new MementoStoreDbContext(_dbContextOptions))
            {
                var memento = new Memento
                {
                    AggregateId = sourceId,
                    MementoJson = serializer.Serialize(oldMemento),
                };
                db.Mementoes.Add(memento);
                await db.SaveChangesAsync();

                sequence = memento.SequenceId;
            }

            var sut = new SqlMementoStore(
                () => new MementoStoreDbContext(_dbContextOptions),
                serializer);

            // Act
            await sut.Save <FakeUser>(sourceId, newMemento, default);

            // Assert
            using (var db = new MementoStoreDbContext(_dbContextOptions))
            {
                Memento actual = await db
                                 .Mementoes
                                 .Where(m => m.SequenceId == sequence)
                                 .SingleOrDefaultAsync();

                actual.Should().NotBeNull();
                actual.AggregateId.Should().Be(sourceId);
                object restored = serializer.Deserialize(actual.MementoJson);
                restored.Should().BeOfType <FakeUserMemento>();
                restored.ShouldBeEquivalentTo(newMemento);
            }
        }
        private async Task <IMemento> FindMemento(
            Guid sourceId,
            CancellationToken cancellationToken)
        {
            using (MementoStoreDbContext context = _dbContextFactory.Invoke())
            {
                Memento entity = await context
                                 .Mementoes
                                 .Where(m => m.AggregateId == sourceId)
                                 .SingleOrDefaultAsync(cancellationToken)
                                 .ConfigureAwait(false);

                if (entity == null)
                {
                    return(null);
                }

                object memento = _serializer.Deserialize(entity.MementoJson);

                return((IMemento)memento);
            }
        }
        private async Task DeleteMemento(
            Guid sourceId,
            CancellationToken cancellationToken)
        {
            using (MementoStoreDbContext context = _dbContextFactory.Invoke())
            {
                Memento entity = await context
                                 .Mementoes
                                 .Where(m => m.AggregateId == sourceId)
                                 .SingleOrDefaultAsync()
                                 .ConfigureAwait(false);

                if (entity == null)
                {
                    return;
                }

                context.Mementoes.Remove(entity);

                await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
            }
        }