Skip to content

Commit

Permalink
Use IUpdateEntry.EntityState instead of ModificationCommand.EntitySta…
Browse files Browse the repository at this point in the history
…te for entities using table splitting.

Fixes #23668
  • Loading branch information
AndriySvyryd committed Dec 15, 2020
1 parent 0e91fa1 commit bcc7910
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 15 deletions.
10 changes: 5 additions & 5 deletions src/EFCore.Relational/Update/Internal/CommandBatchPreparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ private Dictionary<IKeyValueIndex, List<ModificationCommand>> CreateKeyValuePred
.Where(c => c.PrincipalTable.Name == command.TableName && c.PrincipalTable.Schema == command.Schema);

if (!constraints.Any()
|| (command.EntityState == EntityState.Modified
|| (entry.EntityState == EntityState.Modified
&& !foreignKey.PrincipalKey.Properties.Any(p => entry.IsModified(p))))
{
continue;
Expand Down Expand Up @@ -527,7 +527,7 @@ private Dictionary<IKeyValueIndex, List<ModificationCommand>> CreateKeyValuePred
.Where(c => c.Table.Name == command.TableName && c.Table.Schema == command.Schema);

if (!constraints.Any()
|| (command.EntityState == EntityState.Modified
|| (entry.EntityState == EntityState.Modified
&& !foreignKey.Properties.Any(p => entry.IsModified(p))))
{
continue;
Expand Down Expand Up @@ -573,7 +573,7 @@ private void AddForeignKeyEdges(
{
if (!foreignKey.GetMappedConstraints()
.Any(c => c.Table.Name == command.TableName && c.Table.Schema == command.Schema)
|| (command.EntityState == EntityState.Modified
|| (entry.EntityState == EntityState.Modified
&& !foreignKey.Properties.Any(p => entry.IsModified(p))))
{
continue;
Expand Down Expand Up @@ -659,7 +659,7 @@ private void AddUniqueValueEdges(Multigraph<ModificationCommand, IAnnotatable> c
var entry = command.Entries[entryIndex];
foreach (var index in entry.EntityType.GetIndexes().Where(i => i.IsUnique && i.GetMappedTableIndexes().Any()))
{
if (command.EntityState == EntityState.Modified
if (entry.EntityState == EntityState.Modified
&& !index.Properties.Any(p => entry.IsModified(p)))
{
continue;
Expand Down Expand Up @@ -720,7 +720,7 @@ private void AddUniqueValueEdges(Multigraph<ModificationCommand, IAnnotatable> c
{
foreach (var index in entry.EntityType.GetIndexes().Where(i => i.IsUnique && i.GetMappedTableIndexes().Any()))
{
if (command.EntityState == EntityState.Modified
if (entry.EntityState == EntityState.Modified
&& !index.Properties.Any(p => entry.IsModified(p)))
{
continue;
Expand Down
64 changes: 64 additions & 0 deletions test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,70 @@ private class BNum
public string TheWalrus { get; set; }
}

[ConditionalFact]
public void Can_insert_non_owner_principal_for_owned()
{
using var testDatabase = SqlServerTestStore.CreateInitialized(DatabaseName);

var options = Fixture.CreateOptions(testDatabase);
using (var context = new FileContext(options))
{
context.Database.EnsureCreatedResiliently();

var category = new Category { };
context.Categories.Add(category);

context.SaveChanges();

var fileMetadata = new FileMetadata { };
context.FileMetadata.Add(fileMetadata);
category.Picture = new FileSource { FileId = fileMetadata.Id };

context.SaveChanges();
}
}

private class FileContext : DbContext
{
public FileContext(DbContextOptions options)
: base(options)
{
}

public DbSet<FileMetadata> FileMetadata { get; set; }
public DbSet<Category> Categories { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<Category>(builder =>
{
builder.OwnsOne(x => x.Picture, fileSource =>
{
fileSource.HasOne<FileMetadata>().WithOne().HasForeignKey<FileSource>(x => x.FileId);
});
});
}
}

private sealed class FileMetadata
{
public Guid Id { get; set; }
}

private sealed class Category
{
public Guid Id { get; set; }

public FileSource Picture { get; set; }
}

private sealed class FileSource
{
public Guid? FileId { get; set; }
}

[ConditionalFact]
public async Task Can_insert_TPT_dependents_with_identity()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,22 @@ public override void Can_change_dependent_instance_non_derived()
{
base.Can_change_dependent_instance_non_derived();
AssertSql(
@"@p0='Trek Pro Fit Madone 6 Series' (Nullable = false) (Size = 450)
@p1='Repair' (Size = 4000)
SET NOCOUNT ON;
INSERT INTO [LicensedOperators] ([VehicleName], [LicenseType])
VALUES (@p0, @p1);",
//
@"@p1='Trek Pro Fit Madone 6 Series' (Nullable = false) (Size = 450)
@"@p1='Trek Pro Fit Madone 6 Series' (Nullable = false) (Size = 450)
@p0='repairman' (Size = 4000)
SET NOCOUNT ON;
UPDATE [Vehicles] SET [Operator_Name] = @p0
WHERE [Name] = @p1;
SELECT @@ROWCOUNT;",
//
@"SELECT TOP(2) [v].[Name], [v].[SeatingCapacity], [c].[AttachedVehicleName], CASE
//
@"@p2='Trek Pro Fit Madone 6 Series' (Nullable = false) (Size = 450)
@p3='Repair' (Size = 4000)
SET NOCOUNT ON;
INSERT INTO [LicensedOperators] ([VehicleName], [LicenseType])
VALUES (@p2, @p3);",
//
@"SELECT TOP(2) [v].[Name], [v].[SeatingCapacity], [c].[AttachedVehicleName], CASE
WHEN [c].[Name] IS NOT NULL THEN N'CompositeVehicle'
WHEN [p].[Name] IS NOT NULL THEN N'PoweredVehicle'
END AS [Discriminator], [t0].[Name], [t0].[Operator_Name], [t0].[LicenseType], [t0].[Discriminator]
Expand Down

0 comments on commit bcc7910

Please sign in to comment.