public async Task BatchCommands_throws_on_modified_principal_key()
        {
            var configuration = CreateConfiguration();
            var model         = CreateSimpleFKModel();

            var stateEntry = new MixedStateEntry(
                configuration,
                model.GetEntityType(typeof(FakeEntity)), new FakeEntity {
                Id = 42, Value = "Test"
            });
            await stateEntry.SetEntityStateAsync(EntityState.Modified);

            stateEntry.SetPropertyModified(stateEntry.EntityType.GetKey().Properties.Single(), isModified: true);

            var relatedStateEntry = new MixedStateEntry(
                configuration,
                model.GetEntityType(typeof(RelatedFakeEntity)), new RelatedFakeEntity {
                Id = 42
            });
            await relatedStateEntry.SetEntityStateAsync(EntityState.Modified);

            Assert.Equal(
                Strings.FormatPrincipalKeyModified(),
                Assert.Throws <InvalidOperationException>(() => CreateCommandBatchPreparer().BatchCommands(new[] { relatedStateEntry, stateEntry })).Message);
        }
        public async Task BatchCommands_sorts_entities_when_reparenting()
        {
            var configuration = CreateConfiguration();
            var model         = CreateCyclicFKModel();

            var previousParent = new MixedStateEntry(
                configuration,
                model.GetEntityType(typeof(FakeEntity)), new FakeEntity {
                Id = 42, Value = "Test"
            });
            await previousParent.SetEntityStateAsync(EntityState.Deleted);

            var newParent = new MixedStateEntry(
                configuration,
                model.GetEntityType(typeof(FakeEntity)), new FakeEntity {
                Id = 3, Value = "Test"
            });
            await newParent.SetEntityStateAsync(EntityState.Added);

            var relatedStateEntry = new MixedStateEntry(
                configuration,
                model.GetEntityType(typeof(RelatedFakeEntity)), new RelatedFakeEntity {
                Id = 1, RelatedId = 3
            });
            await relatedStateEntry.SetEntityStateAsync(EntityState.Modified);

            relatedStateEntry.OriginalValues[relatedStateEntry.EntityType.GetProperty("RelatedId")] = 42;
            relatedStateEntry.SetPropertyModified(relatedStateEntry.EntityType.GetKey().Properties.Single(), isModified: false);

            var commandBatches = CreateCommandBatchPreparer().BatchCommands(new[] { relatedStateEntry, previousParent, newParent }).ToArray();

            Assert.Equal(
                new[] { newParent, relatedStateEntry, previousParent },
                commandBatches.Select(cb => cb.ModificationCommands.Single()).Select(mc => mc.StateEntries.Single()));
        }
        public async Task BatchCommands_creates_valid_batch_for_modified_entities()
        {
            var stateEntry = new MixedStateEntry(
                CreateConfiguration(),
                CreateSimpleFKModel().GetEntityType(typeof(FakeEntity)), new FakeEntity {
                Id = 42, Value = "Test"
            });

            await stateEntry.SetEntityStateAsync(EntityState.Modified);

            stateEntry.SetPropertyModified(stateEntry.EntityType.GetKey().Properties.Single(), isModified: false);

            var commandBatches = CreateCommandBatchPreparer().BatchCommands(new[] { stateEntry }).ToArray();

            Assert.Equal(1, commandBatches.Count());
            Assert.Equal(1, commandBatches.First().ModificationCommands.Count());

            var command = commandBatches.First().ModificationCommands.Single();

            Assert.Equal(EntityState.Modified, command.EntityState);
            Assert.Equal(2, command.ColumnModifications.Count);

            var columnMod = command.ColumnModifications[0];

            Assert.Equal("Id", columnMod.ColumnName);
            Assert.Same(stateEntry, columnMod.StateEntry);
            Assert.Equal("Id", columnMod.Property.Name);
            Assert.True(columnMod.IsCondition);
            Assert.True(columnMod.IsKey);
            Assert.False(columnMod.IsRead);
            Assert.False(columnMod.IsWrite);

            columnMod = command.ColumnModifications[1];

            Assert.Equal("Value", columnMod.ColumnName);
            Assert.Same(stateEntry, columnMod.StateEntry);
            Assert.Equal("Value", columnMod.Property.Name);
            Assert.False(columnMod.IsCondition);
            Assert.False(columnMod.IsKey);
            Assert.False(columnMod.IsRead);
            Assert.True(columnMod.IsWrite);
        }