From fa64bb539dde2531a26e8cc3b74698d4b7eeda8b Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Tue, 16 Aug 2022 17:06:22 -0700 Subject: [PATCH] Validate that no properties on an entity type are mapped to the same column Fixes #26263 --- .../RelationalPropertyExtensions.cs | 10 +++- .../RelationalModelValidator.cs | 13 +++++ .../TableSharingConcurrencyTokenConvention.cs | 19 +++++-- .../Properties/RelationalStrings.Designer.cs | 24 +++++--- .../Properties/RelationalStrings.resx | 9 ++- .../Internal/SqlServerModelValidator.cs | 26 ++------- .../Builders/TemporalPeriodPropertyBuilder.cs | 5 +- .../Properties/SqlServerStrings.Designer.cs | 8 --- .../Properties/SqlServerStrings.resx | 3 - .../RelationalModelValidatorTest.cs | 56 +++++++++---------- .../SqlServerModelValidatorTest.cs | 35 +----------- .../SqliteModelValidatorTest.cs | 27 --------- 12 files changed, 94 insertions(+), 141 deletions(-) diff --git a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs index d3261e4d04e..6816fcdd2f5 100644 --- a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs @@ -1122,10 +1122,14 @@ public static bool IsColumnNullable(this IReadOnlyProperty property, in StoreObj return false; } - var sharedTableRootProperty = property.FindSharedStoreObjectRootProperty(storeObject); - if (sharedTableRootProperty != null) + if (property is not IConventionProperty conventionProperty + || conventionProperty.GetIsNullableConfigurationSource() == null) { - return sharedTableRootProperty.IsColumnNullable(storeObject); + var sharedTableRootProperty = property.FindSharedStoreObjectRootProperty(storeObject); + if (sharedTableRootProperty != null) + { + return sharedTableRootProperty.IsColumnNullable(storeObject); + } } return property.IsNullable diff --git a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs index db46effec2a..90661d5ef40 100644 --- a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs +++ b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs @@ -1117,6 +1117,19 @@ protected virtual void ValidateSharedColumnsCompatibility( continue; } + if (property.DeclaringEntityType.IsAssignableFrom(duplicateProperty.DeclaringEntityType) + || duplicateProperty.DeclaringEntityType.IsAssignableFrom(property.DeclaringEntityType)) + { + throw new InvalidOperationException( + RelationalStrings.DuplicateColumnNameSameHierarchy( + duplicateProperty.DeclaringEntityType.DisplayName(), + duplicateProperty.Name, + property.DeclaringEntityType.DisplayName(), + property.Name, + columnName, + storeObject.DisplayName())); + } + ValidateCompatible(property, duplicateProperty, columnName, storeObject, logger); } diff --git a/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs b/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs index 99b7f6f44b0..0d9f1a621ef 100644 --- a/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs @@ -99,7 +99,7 @@ public virtual void ProcessModelFinalizing( continue; } - RemoveDerivedEntityTypes(entityTypesMissingConcurrencyColumn); + RemoveDerivedEntityTypes(entityTypesMissingConcurrencyColumn, mappedTypes); foreach (var (conventionEntityType, exampleProperty) in entityTypesMissingConcurrencyColumn) { @@ -194,10 +194,11 @@ public static bool IsConcurrencyTokenMissing( { var declaringEntityType = mappedProperty.DeclaringEntityType; if (declaringEntityType.IsAssignableFrom(entityType) + || entityType.IsAssignableFrom(declaringEntityType) || declaringEntityType.IsInOwnershipPath(entityType) || entityType.IsInOwnershipPath(declaringEntityType)) { - // The concurrency token is on the base type or in the same aggregate + // The concurrency token is on the base type, derived type or in the same aggregate propertyMissing = false; continue; } @@ -220,21 +221,31 @@ public static bool IsConcurrencyTokenMissing( return propertyMissing; } - private static void RemoveDerivedEntityTypes(Dictionary entityTypeDictionary) + private static void RemoveDerivedEntityTypes( + Dictionary entityTypeDictionary, + List mappedTypes) { - foreach (var entityType in entityTypeDictionary.Keys) + foreach (var (entityType, property) in entityTypeDictionary) { + var removed = false; var baseType = entityType.BaseType; while (baseType != null) { if (entityTypeDictionary.ContainsKey(baseType)) { entityTypeDictionary.Remove(entityType); + removed = true; break; } baseType = baseType.BaseType; } + + if (!removed + && entityType.IsAssignableFrom(property.DeclaringEntityType)) + { + entityTypeDictionary.Remove(entityType); + } } } } diff --git a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs index 86b0ea4614f..193f3df3c56 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs +++ b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs @@ -453,6 +453,14 @@ public static string DuplicateColumnNameProviderTypeMismatch(object? entityType1 GetString("DuplicateColumnNameProviderTypeMismatch", nameof(entityType1), nameof(property1), nameof(entityType2), nameof(property2), nameof(columnName), nameof(table), nameof(type1), nameof(type2)), entityType1, property1, entityType2, property2, columnName, table, type1, type2); + /// + /// '{entityType1}.{property1}' and '{entityType2}.{property2}' are both mapped to column '{columnName}' in '{table}', but the properties are contained within the same hierarchy. All properties on an entity type must be mapped to unique different columns. + /// + public static string DuplicateColumnNameSameHierarchy(object? entityType1, object? property1, object? entityType2, object? property2, object? columnName, object? table) + => string.Format( + GetString("DuplicateColumnNameSameHierarchy", nameof(entityType1), nameof(property1), nameof(entityType2), nameof(property2), nameof(columnName), nameof(table)), + entityType1, property1, entityType2, property2, columnName, table); + /// /// '{entityType1}.{property1}' and '{entityType2}.{property2}' are both mapped to column '{columnName}' in '{table}', but are configured with different scales ('{scale1}' and '{scale2}'). /// @@ -1575,14 +1583,6 @@ public static string StoredProcedureOutputParameterNotGenerated(object? entityTy GetString("StoredProcedureOutputParameterNotGenerated", nameof(entityType), nameof(property), nameof(sproc)), entityType, property, sproc); - /// - /// Stored procedure '{sproc]' was configured with a rows affected output parameter or return value, but a valid value was not found when executing the procedure. - /// - public static string StoredProcedureRowsAffectedNotPopulated(object? sproc) - => string.Format( - GetString("StoredProcedureRowsAffectedNotPopulated", nameof(sproc)), - sproc); - /// /// The property '{propertySpecification}' has specific configuration for the stored procedure '{sproc}', but it isn't mapped to a parameter or a result column on that stored procedure. Remove the specific configuration, or map an entity type that contains this property to '{sproc}'. /// @@ -1655,6 +1655,14 @@ public static string StoredProcedureResultColumnParameterConflict(object? entity GetString("StoredProcedureResultColumnParameterConflict", nameof(entityType), nameof(property), nameof(sproc)), entityType, property, sproc); + /// + /// Stored procedure '{sproc}' was configured with a rows affected output parameter or return value, but a valid value was not found when executing the procedure. + /// + public static string StoredProcedureRowsAffectedNotPopulated(object? sproc) + => string.Format( + GetString("StoredProcedureRowsAffectedNotPopulated", nameof(sproc)), + sproc); + /// /// The stored procedure '{sproc}' cannot be configured to return the rows affected because a rows affected parameter or a rows affected result column for this stored procedure already exists. /// diff --git a/src/EFCore.Relational/Properties/RelationalStrings.resx b/src/EFCore.Relational/Properties/RelationalStrings.resx index 3eb627796b8..a885318b96d 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.resx +++ b/src/EFCore.Relational/Properties/RelationalStrings.resx @@ -283,6 +283,9 @@ '{entityType1}.{property1}' and '{entityType2}.{property2}' are both mapped to column '{columnName}' in '{table}', but are configured to use differing provider types ('{type1}' and '{type2}'). + + '{entityType1}.{property1}' and '{entityType2}.{property2}' are both mapped to column '{columnName}' in '{table}', but the properties are contained within the same hierarchy. All properties on an entity type must be mapped to unique different columns. + '{entityType1}.{property1}' and '{entityType2}.{property2}' are both mapped to column '{columnName}' in '{table}', but are configured with different scales ('{scale1}' and '{scale2}'). @@ -1008,9 +1011,6 @@ The property '{entityType}.{property}' is mapped to an output parameter of the stored procedure '{sproc}', but it is not configured as store-generated. Either configure it as store-generated or don't configure the parameter as output. - - Stored procedure '{sproc}' was configured with a rows affected output parameter or return value, but a valid value was not found when executing the procedure. - The property '{propertySpecification}' has specific configuration for the stored procedure '{sproc}', but it isn't mapped to a parameter or a result column on that stored procedure. Remove the specific configuration, or map an entity type that contains this property to '{sproc}'. @@ -1038,6 +1038,9 @@ The property '{entityType}.{property}' is mapped to a result column of the stored procedure '{sproc}', but it is also mapped to an output parameter. A store-generated property can only be mapped to one of these. + + Stored procedure '{sproc}' was configured with a rows affected output parameter or return value, but a valid value was not found when executing the procedure. + The stored procedure '{sproc}' cannot be configured to return the rows affected because a rows affected parameter or a rows affected result column for this stored procedure already exists. diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs index 22a4c46891e..093687b789e 100644 --- a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs +++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs @@ -308,29 +308,11 @@ private static void ValidateTemporalPeriodProperty(IEntityType temporalEntityTyp temporalEntityType.DisplayName(), periodProperty.Name)); } - if (temporalEntityType.GetTableName() is string tableName) + if (periodProperty.ValueGenerated != ValueGenerated.OnAddOrUpdate) { - var storeObjectIdentifier = StoreObjectIdentifier.Table(tableName, temporalEntityType.GetSchema()); - var periodColumnName = periodProperty.GetColumnName(storeObjectIdentifier); - - var propertiesMappedToPeriodColumn = temporalEntityType.GetProperties().Where( - p => p.Name != periodProperty.Name && p.GetColumnName(storeObjectIdentifier) == periodColumnName).ToList(); - foreach (var propertyMappedToPeriodColumn in propertiesMappedToPeriodColumn) - { - if (propertyMappedToPeriodColumn.ValueGenerated != ValueGenerated.OnAddOrUpdate) - { - throw new InvalidOperationException( - SqlServerStrings.TemporalPropertyMappedToPeriodColumnMustBeValueGeneratedOnAddOrUpdate( - temporalEntityType.DisplayName(), propertyMappedToPeriodColumn.Name, nameof(ValueGenerated.OnAddOrUpdate))); - } - - if (propertyMappedToPeriodColumn.TryGetDefaultValue(out var _)) - { - throw new InvalidOperationException( - SqlServerStrings.TemporalPropertyMappedToPeriodColumnCantHaveDefaultValue( - temporalEntityType.DisplayName(), propertyMappedToPeriodColumn.Name)); - } - } + throw new InvalidOperationException( + SqlServerStrings.TemporalPropertyMappedToPeriodColumnMustBeValueGeneratedOnAddOrUpdate( + temporalEntityType.DisplayName(), periodProperty.Name, nameof(ValueGenerated.OnAddOrUpdate))); } // TODO: check that period property is excluded from query (once the annotation is added) diff --git a/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs b/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs index 65154026676..c2cbeb28dc9 100644 --- a/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs +++ b/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Builders; /// Instances of this class are returned from methods when using the API /// and it is not designed to be directly constructed in your application code. /// -public class TemporalPeriodPropertyBuilder +public class TemporalPeriodPropertyBuilder : IInfrastructure { private readonly PropertyBuilder _propertyBuilder; @@ -59,6 +59,9 @@ public virtual TemporalPeriodPropertyBuilder HasPrecision(int precision) return this; } + PropertyBuilder IInfrastructure.Instance + => _propertyBuilder; + #region Hidden System.Object members /// diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs index 05880ce5dd9..ccbf7ea4af5 100644 --- a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs +++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs @@ -333,14 +333,6 @@ public static string TemporalPeriodPropertyMustBeNonNullableDateTime(object? ent GetString("TemporalPeriodPropertyMustBeNonNullableDateTime", nameof(entityType), nameof(propertyName), nameof(dateTimeType)), entityType, propertyName, dateTimeType); - /// - /// Property '{entityType}.{propertyName}' is mapped to the period column and can't have default value specified. - /// - public static string TemporalPropertyMappedToPeriodColumnCantHaveDefaultValue(object? entityType, object? propertyName) - => string.Format( - GetString("TemporalPropertyMappedToPeriodColumnCantHaveDefaultValue", nameof(entityType), nameof(propertyName)), - entityType, propertyName); - /// /// Property '{entityType}.{propertyName}' is mapped to the period column and must have ValueGenerated set to '{valueGeneratedValue}'. /// diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx index 1e30c0c3c20..9815e413d51 100644 --- a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx +++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx @@ -332,9 +332,6 @@ Period property '{entityType}.{propertyName}' must be non-nullable and of type '{dateTimeType}'. - - Property '{entityType}.{propertyName}' is mapped to the period column and can't have default value specified. - Property '{entityType}.{propertyName}' is mapped to the period column and must have ValueGenerated set to '{valueGeneratedValue}'. diff --git a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs index 378bb6eb950..8667a3fc7cb 100644 --- a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs +++ b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs @@ -478,6 +478,20 @@ public virtual void Detects_incompatible_shared_columns_in_shared_table_with_dif modelBuilder); } + [ConditionalFact] + public virtual void Detects_properties_mapped_to_the_same_column_within_hierarchy() + { + var modelBuilder = CreateConventionModelBuilder(); + + modelBuilder.Entity().Property(a => a.P0).HasColumnName(nameof(A.P0)); + modelBuilder.Entity().Property("PC").HasColumnName(nameof(A.P0)); + + VerifyError( + RelationalStrings.DuplicateColumnNameSameHierarchy( + nameof(A), nameof(A.P0), nameof(C), "PC", nameof(A.P0), nameof(A)), + modelBuilder); + } + [ConditionalFact] public virtual void Detects_incompatible_shared_columns_in_shared_table_with_different_provider_types() { @@ -869,35 +883,18 @@ public virtual void Detects_unmapped_foreign_keys_in_entity_splitting() LogLevel.Error); } - - - [ConditionalFact] - public virtual void Detects_duplicate_column_names() - { - var modelBuilder = CreateConventionModelBuilder(); - - modelBuilder.Entity().Property(b => b.Id).HasColumnName("Name"); - modelBuilder.Entity().Property(d => d.Name).HasColumnName("Name").IsRequired(); - - VerifyError( - RelationalStrings.DuplicateColumnNameDataTypeMismatch( - nameof(Animal), nameof(Animal.Id), - nameof(Animal), nameof(Animal.Name), "Name", nameof(Animal), "default_int_mapping", "just_string(max)"), - modelBuilder); - } - [ConditionalFact] public virtual void Detects_duplicate_columns_in_derived_types_with_different_types() { var modelBuilder = CreateConventionModelBuilder(); modelBuilder.Entity(); - modelBuilder.Entity().Property(c => c.Type).HasColumnName("Type").IsRequired(); - modelBuilder.Entity().Property(d => d.Type).HasColumnName("Type"); + modelBuilder.Entity().Property(c => c.Type).HasColumnName("Type").HasColumnType("someInt"); + modelBuilder.Entity().Property(d => d.Type).HasColumnName("Type").HasColumnType("default_int_mapping"); VerifyError( RelationalStrings.DuplicateColumnNameDataTypeMismatch( - nameof(Cat), nameof(Cat.Type), nameof(Dog), nameof(Dog.Type), nameof(Cat.Type), nameof(Animal), "just_string(max)", + nameof(Cat), nameof(Cat.Type), nameof(Dog), nameof(Dog.Type), nameof(Cat.Type), nameof(Animal), "someInt", "default_int_mapping"), modelBuilder); } @@ -1018,16 +1015,17 @@ public virtual void Detects_duplicate_column_names_within_hierarchy_with_differe } [ConditionalFact] - public virtual void Detects_duplicate_column_names_within_hierarchy_with_different_nullability() + public virtual void Detects_duplicate_column_names_with_different_column_nullability() { var modelBuilder = CreateConventionModelBuilder(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity().Property("OtherId").HasColumnName("Id"); + + modelBuilder.Entity().HasOne().WithOne(b => b.A).HasForeignKey(a => a.Id).HasPrincipalKey(b => b.Id).IsRequired(); + modelBuilder.Entity().ToTable("Table").Property(a => a.P0).HasColumnName(nameof(A.P0)).IsRequired(false); + modelBuilder.Entity().ToTable("Table").Property(b => b.P0).HasColumnName(nameof(A.P0)).IsRequired(); VerifyError( RelationalStrings.DuplicateColumnNameNullabilityMismatch( - nameof(Animal), nameof(Animal.Id), nameof(Dog), "OtherId", nameof(Animal.Id), nameof(Animal)), + nameof(A), nameof(A.P0), nameof(B), nameof(A.P0), nameof(A.P0), "Table"), modelBuilder); } @@ -1686,7 +1684,7 @@ private class Address } [ConditionalFact] - public virtual void Detects_missing_concurrency_token_on_the_base_type_without_convention() + public virtual void Passes_with_missing_concurrency_token_on_the_base_type_without_convention() { var modelBuilder = CreateModelBuilderWithoutConvention(); modelBuilder.Entity().ToTable(nameof(Animal)) @@ -1695,9 +1693,7 @@ public virtual void Detects_missing_concurrency_token_on_the_base_type_without_c modelBuilder.Entity() .Property("Version").IsRowVersion().HasColumnName("Version"); - VerifyError( - RelationalStrings.MissingConcurrencyColumn(nameof(Animal), "Version", nameof(Animal)), - modelBuilder); + Validate(modelBuilder); } [ConditionalFact] @@ -1723,7 +1719,7 @@ public virtual void Passes_with_missing_concurrency_token_property_on_the_base_t modelBuilder.Entity() .Property("Version").IsRowVersion().HasColumnName("Version"); - var model = Validate(modelBuilder); + Validate(modelBuilder); } [ConditionalFact] diff --git a/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs b/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs index 83b527d9591..69139900baf 100644 --- a/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs +++ b/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs @@ -11,20 +11,6 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; public class SqlServerModelValidatorTest : RelationalModelValidatorTest { - public override void Detects_duplicate_column_names() - { - var modelBuilder = CreateConventionModelBuilder(); - - modelBuilder.Entity().Property(b => b.Id).HasColumnName("Name"); - modelBuilder.Entity().Property(d => d.Name).IsRequired().HasColumnName("Name"); - - VerifyError( - RelationalStrings.DuplicateColumnNameDataTypeMismatch( - nameof(Animal), nameof(Animal.Id), - nameof(Animal), nameof(Animal.Name), "Name", nameof(Animal), "int", "nvarchar(max)"), - modelBuilder); - } - public override void Detects_duplicate_columns_in_derived_types_with_different_types() { var modelBuilder = CreateConventionModelBuilder(); @@ -838,27 +824,12 @@ public void Temporal_period_property_must_be_mapped_to_datetime2() public void Temporal_all_properties_mapped_to_period_column_must_have_value_generated_OnAddOrUpdate() { var modelBuilder = CreateConventionModelBuilder(); - modelBuilder.Entity().Property(typeof(DateTime), "Start2").HasColumnName("StartColumn").ValueGeneratedOnAddOrUpdate(); - modelBuilder.Entity().Property(typeof(DateTime), "Start3").HasColumnName("StartColumn"); - modelBuilder.Entity().ToTable(tb => tb.IsTemporal(ttb => ttb.HasPeriodStart("Start").HasColumnName("StartColumn"))); + modelBuilder.Entity().ToTable(tb => tb.IsTemporal(ttb => + ttb.HasPeriodStart("Start").HasColumnName("StartColumn").GetInfrastructure().ValueGeneratedNever())); VerifyError( SqlServerStrings.TemporalPropertyMappedToPeriodColumnMustBeValueGeneratedOnAddOrUpdate( - nameof(Dog), "Start3", nameof(ValueGenerated.OnAddOrUpdate)), modelBuilder); - } - - [ConditionalFact] - public void Temporal_all_properties_mapped_to_period_column_cant_have_default_values() - { - var modelBuilder = CreateConventionModelBuilder(); - modelBuilder.Entity().Property(typeof(DateTime), "Start2").HasColumnName("StartColumn").ValueGeneratedOnAddOrUpdate(); - modelBuilder.Entity().Property(typeof(DateTime), "Start3").HasColumnName("StartColumn").ValueGeneratedOnAddOrUpdate() - .HasDefaultValue(DateTime.MinValue); - modelBuilder.Entity().ToTable(tb => tb.IsTemporal(ttb => ttb.HasPeriodStart("Start").HasColumnName("StartColumn"))); - - VerifyError( - SqlServerStrings.TemporalPropertyMappedToPeriodColumnCantHaveDefaultValue( - nameof(Dog), "Start3"), modelBuilder); + nameof(Dog), "Start", nameof(ValueGenerated.OnAddOrUpdate)), modelBuilder); } [ConditionalFact] diff --git a/test/EFCore.Sqlite.Tests/Infrastructure/SqliteModelValidatorTest.cs b/test/EFCore.Sqlite.Tests/Infrastructure/SqliteModelValidatorTest.cs index fb7d17922d2..fd176d9a659 100644 --- a/test/EFCore.Sqlite.Tests/Infrastructure/SqliteModelValidatorTest.cs +++ b/test/EFCore.Sqlite.Tests/Infrastructure/SqliteModelValidatorTest.cs @@ -9,33 +9,6 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; public class SqliteModelValidatorTest : RelationalModelValidatorTest { - public override void Detects_duplicate_column_names() - { - var modelBuilder = CreateConventionModelBuilder(); - - modelBuilder.Entity().Property(b => b.Id).HasColumnName("Name"); - modelBuilder.Entity().Property(d => d.Name).IsRequired().HasColumnName("Name"); - - VerifyError( - RelationalStrings.DuplicateColumnNameDataTypeMismatch( - nameof(Animal), nameof(Animal.Id), - nameof(Animal), nameof(Animal.Name), "Name", nameof(Animal), "INTEGER", "TEXT"), - modelBuilder); - } - - public override void Detects_duplicate_columns_in_derived_types_with_different_types() - { - var modelBuilder = CreateConventionModelBuilder(); - modelBuilder.Entity(); - - modelBuilder.Entity().Property(c => c.Type).IsRequired().HasColumnName("Type"); - modelBuilder.Entity().Property(d => d.Type).HasColumnName("Type"); - - VerifyError( - RelationalStrings.DuplicateColumnNameDataTypeMismatch( - typeof(Cat).Name, "Type", typeof(Dog).Name, "Type", "Type", nameof(Animal), "TEXT", "INTEGER"), modelBuilder); - } - [ConditionalFact] public virtual void Detects_duplicate_column_names_within_hierarchy_with_different_srid() {