Skip to content

Commit

Permalink
Don't validate shared columns have the same provider type unless they…
Browse files Browse the repository at this point in the history
… are used in a key, foreign key or a unique index

Fixes #29859
  • Loading branch information
AndriySvyryd committed Jan 4, 2023
1 parent b9f27aa commit 04429be
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
11 changes: 10 additions & 1 deletion src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure;
/// </remarks>
public class RelationalModelValidator : ModelValidator
{
private static readonly bool QuirkEnabled29859
= AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue29859", out var enabled) && enabled;
private static readonly bool QuirkEnabled29531
= AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue29531", out var enabled) && enabled;

Expand Down Expand Up @@ -1423,7 +1425,14 @@ protected virtual void ValidateCompatible(
?? duplicateTypeMapping.ClrType;
}

if (currentProviderType != previousProviderType)
if (currentProviderType != previousProviderType
&& (QuirkEnabled29859
|| property.IsKey()
|| duplicateProperty.IsKey()
|| property.IsForeignKey()
|| duplicateProperty.IsForeignKey()
|| (property.IsIndex() && property.GetContainingIndexes().Any(i => i.IsUnique))
|| (duplicateProperty.IsIndex() && duplicateProperty.GetContainingIndexes().Any(i => i.IsUnique))))
{
throw new InvalidOperationException(
RelationalStrings.DuplicateColumnNameProviderTypeMismatch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ public virtual void Detects_properties_mapped_to_the_same_column_within_hierarch
}

[ConditionalFact]
public virtual void Detects_incompatible_shared_columns_in_shared_table_with_different_provider_types()
public virtual void Passes_for_incompatible_shared_columns_in_shared_table_with_different_provider_types()
{
var modelBuilder = CreateConventionModelBuilder();

Expand All @@ -503,6 +503,57 @@ public virtual void Detects_incompatible_shared_columns_in_shared_table_with_dif
modelBuilder.Entity<B>().Property(b => b.P0).HasColumnName(nameof(A.P0)).HasColumnType("someInt");
modelBuilder.Entity<B>().ToTable("Table");

Validate(modelBuilder);
}

[ConditionalFact]
public virtual void Detects_incompatible_shared_columns_in_shared_table_with_different_provider_types_for_unique_indexes()
{
var modelBuilder = CreateConventionModelBuilder();

modelBuilder.Entity<A>().HasOne<B>().WithOne(b => b.A).HasForeignKey<A>(a => a.Id).HasPrincipalKey<B>(b => b.Id).IsRequired();
modelBuilder.Entity<A>().Property(a => a.P0).HasColumnName(nameof(A.P0)).HasColumnType("someInt").HasConversion<long>();
modelBuilder.Entity<A>().ToTable("Table");
modelBuilder.Entity<B>().Property(b => b.P0).HasColumnName(nameof(A.P0)).HasColumnType("someInt");
modelBuilder.Entity<B>().ToTable("Table");
modelBuilder.Entity<A>().HasIndex(a => a.P0).IsUnique();

VerifyError(
RelationalStrings.DuplicateColumnNameProviderTypeMismatch(
nameof(A), nameof(A.P0), nameof(B), nameof(B.P0), nameof(B.P0), "Table", "long", "int"),
modelBuilder);
}

[ConditionalFact]
public virtual void Detects_incompatible_shared_columns_in_shared_table_with_different_provider_types_for_keys()
{
var modelBuilder = CreateConventionModelBuilder();

modelBuilder.Entity<A>().HasOne<B>().WithOne(b => b.A).HasForeignKey<A>(a => a.Id).HasPrincipalKey<B>(b => b.Id).IsRequired();
modelBuilder.Entity<A>().Property(a => a.P0).HasColumnName(nameof(A.P0)).HasColumnType("someInt").HasConversion<long>();
modelBuilder.Entity<A>().ToTable("Table");
modelBuilder.Entity<B>().Property(b => b.P0).HasColumnName(nameof(A.P0)).HasColumnType("someInt");
modelBuilder.Entity<B>().ToTable("Table");
modelBuilder.Entity<A>().HasAlternateKey(a => a.P0);

VerifyError(
RelationalStrings.DuplicateColumnNameProviderTypeMismatch(
nameof(A), nameof(A.P0), nameof(B), nameof(B.P0), nameof(B.P0), "Table", "long", "int"),
modelBuilder);
}

[ConditionalFact]
public virtual void Detects_incompatible_shared_columns_in_shared_table_with_different_provider_types_for_foreign_keys()
{
var modelBuilder = CreateConventionModelBuilder();

modelBuilder.Entity<A>().HasOne<B>().WithOne(b => b.A).HasForeignKey<A>(a => a.Id).HasPrincipalKey<B>(b => b.Id).IsRequired();
modelBuilder.Entity<A>().Property(a => a.P0).HasColumnName(nameof(A.P0)).HasColumnType("someInt").HasConversion<long>();
modelBuilder.Entity<A>().ToTable("Table");
modelBuilder.Entity<B>().Property(b => b.P0).HasColumnName(nameof(A.P0)).HasColumnType("someInt");
modelBuilder.Entity<B>().ToTable("Table");
modelBuilder.Entity<A>().HasOne<B>().WithOne().HasForeignKey<A>(a => a.P0).HasPrincipalKey<B>(b => b.Id);

VerifyError(
RelationalStrings.DuplicateColumnNameProviderTypeMismatch(
nameof(A), nameof(A.P0), nameof(B), nameof(B.P0), nameof(B.P0), "Table", "long", "int"),
Expand Down

0 comments on commit 04429be

Please sign in to comment.