Skip to content

Commit

Permalink
Take the value converter into account when creating concurrency token…
Browse files Browse the repository at this point in the history
…s for table sharing

Fixes #22584
Fixes #27888
  • Loading branch information
AndriySvyryd authored Sep 2, 2022
1 parent d7d6d91 commit 2f8ee64
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,12 @@ public virtual void ProcessModelFinalizing(

foreach (var (conventionEntityType, exampleProperty) in entityTypesMissingConcurrencyColumn)
{
var providerType = exampleProperty.GetProviderClrType()
?? (exampleProperty.GetValueConverter() ??
exampleProperty.FindTypeMapping()?.Converter)?.ProviderClrType
?? exampleProperty.ClrType;
conventionEntityType.Builder.CreateUniqueProperty(
exampleProperty.ClrType,
providerType,
ConcurrencyPropertyPrefix + exampleProperty.Name,
!exampleProperty.IsNullable)!
.HasColumnName(concurrencyColumnName)!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1713,7 +1713,7 @@ public virtual void Detects_missing_concurrency_token_on_the_sharing_type_withou
}

[ConditionalFact]
public virtual void Passes_with_missing_concurrency_token_property_on_the_base_type()
public virtual void Passes_for_missing_concurrency_token_property_on_the_base_type()
{
var modelBuilder = CreateConventionModelBuilder();
modelBuilder.Entity<Person>().ToTable(nameof(Animal))
Expand All @@ -1726,7 +1726,7 @@ public virtual void Passes_with_missing_concurrency_token_property_on_the_base_t
}

[ConditionalFact]
public virtual void Passes_with_missing_concurrency_token_property_on_the_base_type_when_derived_is_sharing()
public virtual void Passes_for_missing_concurrency_token_property_on_the_base_type_when_derived_is_sharing()
{
var modelBuilder = CreateConventionModelBuilder();
modelBuilder.Entity<Person>().ToTable(nameof(Animal))
Expand All @@ -1743,14 +1743,20 @@ public virtual void Passes_with_missing_concurrency_token_property_on_the_base_t
}

[ConditionalFact]
public virtual void Passes_with_missing_concurrency_token_property_on_the_sharing_type()
public virtual void Passes_for_missing_concurrency_token_property_on_the_sharing_type()
{
var modelBuilder = CreateConventionModelBuilder();
modelBuilder.Entity<Person>().ToTable(nameof(Animal));
modelBuilder.Entity<Animal>().HasOne(a => a.FavoritePerson).WithOne().HasForeignKey<Person>(p => p.Id);
modelBuilder.Entity<Animal>().Property<byte[]>("Version").IsRowVersion().HasColumnName("Version");
modelBuilder.Entity<Animal>().Property<ulong>("Version")
.HasConversion<byte[]>().IsRowVersion();

Validate(modelBuilder);
var model = Validate(modelBuilder);

var personType = model.FindEntityType(typeof(Person))!;
var concurrencyProperty = personType.GetDeclaredProperties().Single(p => p.IsConcurrencyToken);
Assert.Equal("Version", concurrencyProperty.GetColumnName());
Assert.Equal(typeof(byte[]), concurrencyProperty.ClrType);
}

[ConditionalFact]
Expand All @@ -1777,9 +1783,17 @@ public virtual void Passes_for_missing_concurrency_token_on_owner()
modelBuilder.Entity<Cat>().OwnsOne(
a => a.FavoritePerson,
pb => pb.Property<byte[]>("Version").IsRowVersion().HasColumnName("Version"));
modelBuilder.Entity<Dog>().Ignore(d => d.FavoritePerson);
modelBuilder.Entity<Dog>().OwnsOne(
a => a.FavoritePerson);

Validate(modelBuilder);
var model = Validate(modelBuilder);

var animalType = model.FindEntityType(typeof(Animal))!;
Assert.Null(animalType.GetDeclaredProperties().SingleOrDefault(p => p.IsConcurrencyToken));

var dogType = model.FindEntityType(typeof(Dog))!;
var concurrencyProperty = dogType.GetDeclaredProperties().Single(p => p.IsConcurrencyToken);
Assert.Equal("Version", concurrencyProperty.GetColumnName());
}

[ConditionalFact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ public virtual void TPC_identifying_FKs_are_created_on_all_tables()
{
b.ToTable("Ingredients");
b.Ignore(i => i.BigMak);
b.HasIndex(e => e.BurgerId);
b.UseTpcMappingStrategy();
});
modelBuilder.Entity<Bun>(
Expand All @@ -388,10 +389,8 @@ public virtual void TPC_identifying_FKs_are_created_on_all_tables()
Assert.Empty(principalType.GetIndexes());
Assert.Null(principalType.FindDiscriminatorProperty());

var ingredientType = model.FindEntityType(typeof(Ingredient));

var bunType = model.FindEntityType(typeof(Bun))!;
Assert.Empty(bunType.GetIndexes());
Assert.Empty(bunType.GetDeclaredIndexes());
Assert.Null(bunType.FindDiscriminatorProperty());
var bunFk = bunType.GetDeclaredForeignKeys().Single();
Assert.Equal("FK_Buns_BigMak_Id", bunFk.GetConstraintName());
Expand All @@ -404,12 +403,20 @@ public virtual void TPC_identifying_FKs_are_created_on_all_tables()
Assert.Empty(bunType.GetDeclaredForeignKeys().Where(fk => fk.IsBaseLinking()));

var sesameBunType = model.FindEntityType(typeof(SesameBun))!;
Assert.Empty(sesameBunType.GetIndexes());
Assert.Empty(sesameBunType.GetDeclaredIndexes());
Assert.Empty(sesameBunType.GetDeclaredForeignKeys());
Assert.Equal(
"FK_SesameBuns_BigMak_Id", bunFk.GetConstraintName(
StoreObjectIdentifier.Create(sesameBunType, StoreObjectType.Table)!.Value,
StoreObjectIdentifier.Create(principalType, StoreObjectType.Table)!.Value));

var ingredientType = model.FindEntityType(typeof(Ingredient))!;
var ingredientIndex = ingredientType.GetDeclaredIndexes().Single();
Assert.Equal("IX_Ingredients_BurgerId", ingredientIndex.GetDatabaseName());
Assert.Equal("IX_SesameBuns_BurgerId",
ingredientIndex.GetDatabaseName(StoreObjectIdentifier.Create(sesameBunType, StoreObjectType.Table)!.Value));
Assert.Equal("IX_Buns_BurgerId",
ingredientIndex.GetDatabaseName(StoreObjectIdentifier.Create(bunType, StoreObjectType.Table)!.Value));
}

[ConditionalFact]
Expand Down

0 comments on commit 2f8ee64

Please sign in to comment.