diff --git a/eng/Versions.props b/eng/Versions.props
index 253fefa1435..914fd31db50 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -49,7 +49,7 @@
1.20.0
1.4.0
1.15.1
- 3.0.2
+ 3.0.3
2.3.2
diff --git a/src/EFCore/EFCore.baseline.json b/src/EFCore/EFCore.baseline.json
index b52c3b307fa..bffa286d455 100644
--- a/src/EFCore/EFCore.baseline.json
+++ b/src/EFCore/EFCore.baseline.json
@@ -3851,7 +3851,10 @@
"Member": "static string ConflictingKeylessAndPrimaryKeyAttributes(object? entity);"
},
{
- "Member": "static string ConflictingPropertyOrNavigation(object? member, object? type, object? conflictingType);"
+ "Member": "static string ConflictingPropertyOrNavigationOnBaseType(object? member, object? type, object? conflictingMemberKind, object? conflictingType);"
+ },
+ {
+ "Member": "static string ConflictingPropertyOrNavigationWithKind(object? member, object? type, object? conflictingMemberKind);"
},
{
"Member": "static string ConflictingRelationshipConversions(object? entityType, object? property, object? valueConversion, object? conflictingValueConversion);"
diff --git a/src/EFCore/Metadata/Builders/ReferenceNavigationBuilder.cs b/src/EFCore/Metadata/Builders/ReferenceNavigationBuilder.cs
index dcb060b5d62..f9d66346752 100644
--- a/src/EFCore/Metadata/Builders/ReferenceNavigationBuilder.cs
+++ b/src/EFCore/Metadata/Builders/ReferenceNavigationBuilder.cs
@@ -238,8 +238,8 @@ private InternalForeignKeyBuilder WithOneBuilder(MemberIdentity reference)
&& ReferenceName == referenceName)
{
throw new InvalidOperationException(
- CoreStrings.ConflictingPropertyOrNavigation(
- referenceName, RelatedEntityType.DisplayName(), RelatedEntityType.DisplayName()));
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(
+ referenceName, RelatedEntityType.DisplayName(), "navigation"));
}
var pointsToPrincipal = !foreignKey.IsSelfReferencing()
diff --git a/src/EFCore/Metadata/Internal/EntityType.cs b/src/EFCore/Metadata/Internal/EntityType.cs
index 6cc6fcf2bef..a5b15b86883 100644
--- a/src/EFCore/Metadata/Internal/EntityType.cs
+++ b/src/EFCore/Metadata/Internal/EntityType.cs
@@ -1451,16 +1451,14 @@ public virtual Navigation AddNavigation(MemberIdentity navigationMember, Foreign
}
throw new InvalidOperationException(
- CoreStrings.ConflictingPropertyOrNavigation(
- name, DisplayName(), duplicateNavigation.DeclaringEntityType.DisplayName()));
+ duplicateNavigation.FormatConflictingMemberMessage(name, this));
}
var duplicateProperty = FindMembersInHierarchy(name).FirstOrDefault();
if (duplicateProperty != null)
{
throw new InvalidOperationException(
- CoreStrings.ConflictingPropertyOrNavigation(
- name, DisplayName(), ((IReadOnlyTypeBase)duplicateProperty.DeclaringType).DisplayName()));
+ duplicateProperty.FormatConflictingMemberMessage(name, this));
}
Check.DebugAssert(
@@ -1633,8 +1631,7 @@ public virtual IEnumerable GetNavigations()
if (duplicateProperty != null)
{
throw new InvalidOperationException(
- CoreStrings.ConflictingPropertyOrNavigation(
- name, DisplayName(), duplicateProperty.DeclaringType.DisplayName()));
+ duplicateProperty.FormatConflictingMemberMessage(name, this));
}
if (memberInfo != null)
@@ -2286,9 +2283,7 @@ public virtual ServiceProperty AddServiceProperty(
if (duplicateMember != null)
{
throw new InvalidOperationException(
- CoreStrings.ConflictingPropertyOrNavigation(
- name, DisplayName(),
- ((IReadOnlyTypeBase)duplicateMember.DeclaringType).DisplayName()));
+ duplicateMember.FormatConflictingMemberMessage(name, this));
}
ValidateClrMember(name, memberInfo, false);
diff --git a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs
index 72f06816d57..b7f507e130d 100644
--- a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs
+++ b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs
@@ -541,8 +541,7 @@ public override void RemoveMembersInHierarchy(string propertyName, Configuration
if (conflictingNavigation.GetConfigurationSource() == ConfigurationSource.Explicit)
{
throw new InvalidOperationException(
- CoreStrings.ConflictingPropertyOrNavigation(
- propertyName, Metadata.DisplayName(), conflictingNavigation.DeclaringEntityType.DisplayName()));
+ conflictingNavigation.FormatConflictingMemberMessage(propertyName, Metadata));
}
var foreignKey = conflictingNavigation.ForeignKey;
diff --git a/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs b/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
index 19b27dace99..0588611cc57 100644
--- a/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
+++ b/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
@@ -338,6 +338,56 @@ or PropertyAccessMode.FieldDuringConstruction
return false;
}
+ ///
+ /// Builds the message for the diagnostic that fires when a member conflicts with an existing
+ /// member on the structural type or one of its base types. The kind of the conflicting member
+ /// is humanized via so the user-facing message uses stable
+ /// labels like "property", "complex property", "navigation", "skip navigation", or
+ /// "service property" regardless of whether the conflicting member came from a model or a
+ /// runtime model.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ public static string FormatConflictingMemberMessage(
+ this IReadOnlyPropertyBase conflictingMember,
+ string newMemberName,
+ IReadOnlyTypeBase owningType)
+ {
+ var conflictingMemberKind = GetMemberKindString(conflictingMember);
+ var owningTypeDisplayName = owningType.DisplayName();
+
+ // Compare the actual metadata instances rather than display names to avoid false positives when
+ // two distinct types share a simple name (e.g. same name in different namespaces or hierarchies).
+ return conflictingMember.DeclaringType == owningType
+ ? CoreStrings.ConflictingPropertyOrNavigationWithKind(newMemberName, owningTypeDisplayName, conflictingMemberKind)
+ : CoreStrings.ConflictingPropertyOrNavigationOnBaseType(
+ newMemberName,
+ owningTypeDisplayName,
+ conflictingMemberKind,
+ ((IReadOnlyTypeBase)conflictingMember.DeclaringType).DisplayName());
+ }
+
+ ///
+ /// Returns a human-readable label for the kind of the given member (e.g. "property",
+ /// "complex property", "navigation", "skip navigation", "service property"). Used to build
+ /// user-facing diagnostic messages without coupling the message text to internal CLR class
+ /// names (such as RuntimeProperty or SkipNavigation).
+ ///
+ private static string GetMemberKindString(IReadOnlyPropertyBase member)
+ => member switch
+ {
+ IReadOnlyComplexProperty => "complex property",
+ IReadOnlySkipNavigation => "skip navigation",
+ IReadOnlyNavigation => "navigation",
+ IReadOnlyServiceProperty => "service property",
+ IReadOnlyProperty => "property",
+ _ => member.GetType().Name
+ };
+
private static string GetNoFieldErrorMessage(IPropertyBase propertyBase)
=> propertyBase.DeclaringType switch
{
diff --git a/src/EFCore/Metadata/Internal/TypeBase.cs b/src/EFCore/Metadata/Internal/TypeBase.cs
index 0cfe3f25afc..3b3fe513e32 100644
--- a/src/EFCore/Metadata/Internal/TypeBase.cs
+++ b/src/EFCore/Metadata/Internal/TypeBase.cs
@@ -634,9 +634,7 @@ private void CheckDiscriminatorProperty(Property? property)
if (conflictingMember != null)
{
throw new InvalidOperationException(
- CoreStrings.ConflictingPropertyOrNavigation(
- name, DisplayName(),
- ((IReadOnlyTypeBase)conflictingMember.DeclaringType).DisplayName()));
+ conflictingMember.FormatConflictingMemberMessage(name, this));
}
if (memberInfo != null)
@@ -1082,9 +1080,7 @@ public virtual IReadOnlyDictionary GetRuntimeFields()
if (conflictingMember != null)
{
throw new InvalidOperationException(
- CoreStrings.ConflictingPropertyOrNavigation(
- name, DisplayName(),
- conflictingMember.DeclaringType.DisplayName()));
+ conflictingMember.FormatConflictingMemberMessage(name, this));
}
if (memberInfo != null)
diff --git a/src/EFCore/Properties/CoreStrings.Designer.cs b/src/EFCore/Properties/CoreStrings.Designer.cs
index bf9d212a078..7f65927b402 100644
--- a/src/EFCore/Properties/CoreStrings.Designer.cs
+++ b/src/EFCore/Properties/CoreStrings.Designer.cs
@@ -877,12 +877,20 @@ public static string ConflictingKeylessAndPrimaryKeyAttributes(object? entity)
entity);
///
- /// The property or navigation '{member}' cannot be added to the '{type}' type because a property or navigation with the same name already exists on the '{conflictingType}' type.
+ /// The member '{member}' cannot be added to the '{type}' type because a {conflictingMemberKind} with the same name already exists on the '{conflictingType}' type. Remove the existing {conflictingMemberKind} first.
///
- public static string ConflictingPropertyOrNavigation(object? member, object? type, object? conflictingType)
+ public static string ConflictingPropertyOrNavigationOnBaseType(object? member, object? type, object? conflictingMemberKind, object? conflictingType)
=> string.Format(
- GetString("ConflictingPropertyOrNavigation", nameof(member), nameof(type), nameof(conflictingType)),
- member, type, conflictingType);
+ GetString("ConflictingPropertyOrNavigationOnBaseType", nameof(member), nameof(type), nameof(conflictingMemberKind), nameof(conflictingType)),
+ member, type, conflictingMemberKind, conflictingType);
+
+ ///
+ /// The member '{member}' cannot be added to the '{type}' type because a {conflictingMemberKind} with the same name already exists. Remove the existing {conflictingMemberKind} first.
+ ///
+ public static string ConflictingPropertyOrNavigationWithKind(object? member, object? type, object? conflictingMemberKind)
+ => string.Format(
+ GetString("ConflictingPropertyOrNavigationWithKind", nameof(member), nameof(type), nameof(conflictingMemberKind)),
+ member, type, conflictingMemberKind);
///
/// The property '{entityType}.{property}' participates in several relationship chains that have conflicting conversions: '{valueConversion}' and '{conflictingValueConversion}'.
diff --git a/src/EFCore/Properties/CoreStrings.resx b/src/EFCore/Properties/CoreStrings.resx
index 673e2719b39..ba84a1aebd1 100644
--- a/src/EFCore/Properties/CoreStrings.resx
+++ b/src/EFCore/Properties/CoreStrings.resx
@@ -438,8 +438,11 @@
The entity type '{entity}' has both [Keyless] and [PrimaryKey] attributes; one must be removed.
-
- The property or navigation '{member}' cannot be added to the '{type}' type because a property or navigation with the same name already exists on the '{conflictingType}' type.
+
+ The member '{member}' cannot be added to the '{type}' type because a {conflictingMemberKind} with the same name already exists on the '{conflictingType}' type. Remove the existing {conflictingMemberKind} first.
+
+
+ The member '{member}' cannot be added to the '{type}' type because a {conflictingMemberKind} with the same name already exists. Remove the existing {conflictingMemberKind} first.
The property '{entityType}.{property}' participates in several relationship chains that have conflicting conversions: '{valueConversion}' and '{conflictingValueConversion}'.
diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToOne.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToOne.cs
index 5c446e28541..9cedb5df661 100644
--- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToOne.cs
+++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToOne.cs
@@ -3050,7 +3050,7 @@ public virtual void Throws_on_duplicate_navigation_when_self_referencing()
var modelBuilder = CreateModelBuilder();
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation("SelfRef1", nameof(SelfRef), nameof(SelfRef)),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind("SelfRef1", nameof(SelfRef), "navigation"),
Assert.Throws(()
=> modelBuilder.Entity().HasOne(e => e.SelfRef1).WithOne(e => e.SelfRef1)).Message);
}
diff --git a/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.BaseType.cs b/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.BaseType.cs
index 55a33981625..13d94f1e9ab 100644
--- a/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.BaseType.cs
+++ b/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.BaseType.cs
@@ -370,7 +370,7 @@ public void Adding_property_throws_when_parent_type_has_property_with_same_name(
b.BaseType = a;
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation("G", typeof(B).Name, typeof(A).Name),
+ CoreStrings.ConflictingPropertyOrNavigationOnBaseType("G", typeof(B).Name, "property", typeof(A).Name),
Assert.Throws(() => b.AddProperty("G")).Message);
}
@@ -389,7 +389,7 @@ public void Adding_property_throws_when_grandparent_type_has_property_with_same_
d.BaseType = c;
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation("G", typeof(D).Name, typeof(A).Name),
+ CoreStrings.ConflictingPropertyOrNavigationOnBaseType("G", typeof(D).Name, "property", typeof(A).Name),
Assert.Throws(() => d.AddProperty("G")).Message);
}
@@ -406,7 +406,7 @@ public void Adding_property_throws_when_child_type_has_property_with_same_name()
b.AddProperty(A.GProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation("G", typeof(A).Name, typeof(B).Name),
+ CoreStrings.ConflictingPropertyOrNavigationOnBaseType("G", typeof(A).Name, "property", typeof(B).Name),
Assert.Throws(() => a.AddProperty(A.GProperty)).Message);
}
@@ -426,7 +426,7 @@ public void Adding_property_throws_when_grandchild_type_has_property_with_same_n
d.AddProperty(A.GProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation("G", typeof(A).Name, typeof(D).Name),
+ CoreStrings.ConflictingPropertyOrNavigationOnBaseType("G", typeof(A).Name, "property", typeof(D).Name),
Assert.Throws(() => a.AddProperty(A.GProperty)).Message);
}
diff --git a/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs b/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs
index baa296d820e..7180c5b7039 100644
--- a/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs
+++ b/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs
@@ -952,7 +952,7 @@ public void Adding_a_new_navigation_with_a_name_that_conflicts_with_a_property_t
orderType.AddProperty("Customer");
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation("Customer", typeof(Order).Name, typeof(Order).Name),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind("Customer", typeof(Order).Name, "property"),
Assert.Throws(() => customerForeignKey.SetDependentToPrincipal("Customer")).Message);
}
@@ -970,7 +970,7 @@ public void Adding_a_new_navigation_with_a_name_that_conflicts_with_a_service_pr
orderType.AddServiceProperty(Order.CustomerProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Customer), nameof(Order), nameof(Order)),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(Order.Customer), nameof(Order), "service property"),
Assert.Throws(() => customerForeignKey.SetDependentToPrincipal(nameof(Order.Customer))).Message);
}
@@ -1154,7 +1154,7 @@ public void Throws_when_adding_same_self_referencing_navigation_twice()
fk.SetPrincipalToDependent(SelfRef.SelfRef1Property);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(SelfRef.SelfRef1), typeof(SelfRef).Name, typeof(SelfRef).Name),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(SelfRef.SelfRef1), typeof(SelfRef).Name, "navigation"),
Assert.Throws(() => fk.SetDependentToPrincipal(SelfRef.SelfRef1Property)).Message);
}
@@ -1363,7 +1363,7 @@ public void Adding_skip_navigation_with_a_name_that_conflicts_with_another_skip_
navigation.SetForeignKey(orderProductForeignKey);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Products), typeof(Order).Name, typeof(Order).Name),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(Order.Products), typeof(Order).Name, "skip navigation"),
Assert.Throws(() =>
orderEntity.AddSkipNavigation(
nameof(Order.Products), null, null, productEntity, true, false)).Message);
@@ -1388,7 +1388,7 @@ public void Adding_skip_navigation_with_a_name_that_conflicts_with_a_navigation_
customerForeignKey.SetPrincipalToDependent(nameof(Order.Products));
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Products), typeof(Order).Name, typeof(Order).Name),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(Order.Products), typeof(Order).Name, "navigation"),
Assert.Throws(() =>
orderEntity.AddSkipNavigation(
nameof(Order.Products), null, null, productEntity, true, false)).Message);
@@ -1410,7 +1410,7 @@ public void Adding_skip_navigation_with_a_name_that_conflicts_with_a_property_th
orderEntity.AddProperty(nameof(Order.Products));
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Products), typeof(Order).Name, typeof(Order).Name),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(Order.Products), typeof(Order).Name, "property"),
Assert.Throws(() =>
orderEntity.AddSkipNavigation(
nameof(Order.Products), null, null, productEntity, true, false)).Message);
@@ -1432,7 +1432,7 @@ public void Adding_skip_navigation_with_a_name_that_conflicts_with_a_service_pro
orderEntity.AddServiceProperty(Order.ProductsProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Products), typeof(Order).Name, typeof(Order).Name),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(Order.Products), typeof(Order).Name, "service property"),
Assert.Throws(() =>
orderEntity.AddSkipNavigation(
nameof(Order.Products), null, null, productEntity, true, false)).Message);
@@ -2046,7 +2046,7 @@ public void Adding_a_new_property_with_a_name_that_already_exists_throws()
entityType.AddProperty(Customer.IdProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation("Id", typeof(Customer).Name, typeof(Customer).Name),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind("Id", typeof(Customer).Name, "property"),
Assert.Throws(() => entityType.AddProperty("Id")).Message);
}
@@ -2064,7 +2064,7 @@ public void Adding_a_new_property_with_a_name_that_conflicts_with_a_navigation_t
customerForeignKey.SetDependentToPrincipal(Order.CustomerProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation("Customer", typeof(Order).Name, typeof(Order).Name),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind("Customer", typeof(Order).Name, "navigation"),
Assert.Throws(() => orderType.AddProperty("Customer")).Message);
}
@@ -2082,7 +2082,7 @@ public void Adding_a_new_property_with_a_name_that_conflicts_with_a_service_prop
customerForeignKey.SetDependentToPrincipal(Order.CustomerProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Customer), nameof(Order), nameof(Order)),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(Order.Customer), nameof(Order), "navigation"),
Assert.Throws(() => orderType.AddServiceProperty(Order.CustomerProperty)).Message);
}
@@ -2094,7 +2094,7 @@ public void Adding_a_new_service_property_with_a_name_that_conflicts_with_a_prop
entityType.AddProperty(Customer.OrdersProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(Customer.Orders), nameof(Customer), nameof(Customer)),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(Customer.Orders), nameof(Customer), "property"),
Assert.Throws(() => entityType.AddServiceProperty(Customer.OrdersProperty)).Message);
}
@@ -2112,7 +2112,7 @@ public void Adding_a_new_service_property_with_a_name_that_conflicts_with_a_navi
customerForeignKey.SetDependentToPrincipal(Order.CustomerProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Customer), nameof(Order), nameof(Order)),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(Order.Customer), nameof(Order), "navigation"),
Assert.Throws(() => orderType.AddServiceProperty(Order.CustomerProperty)).Message);
}
@@ -2124,7 +2124,7 @@ public void Adding_a_new_service_property_with_a_name_that_already_exists_throws
entityType.AddServiceProperty(Customer.OrdersProperty);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(nameof(Customer.Orders), nameof(Customer), nameof(Customer)),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(nameof(Customer.Orders), nameof(Customer), "service property"),
Assert.Throws(() => entityType.AddServiceProperty(Customer.OrdersProperty)).Message);
}
@@ -2202,7 +2202,7 @@ public void AddIndexerProperty_throws_when_entitytype_have_property_with_same_na
entityType.AddProperty("Nation", typeof(string));
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation("Nation", entityType.DisplayName(), entityType.DisplayName()),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind("Nation", entityType.DisplayName(), "property"),
Assert.Throws(() => entityType.AddIndexerProperty("Nation", typeof(string))).Message);
Assert.Equal(
diff --git a/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs b/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs
index e96a0e82c7f..7b56e19f017 100644
--- a/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs
+++ b/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs
@@ -1667,8 +1667,8 @@ public void Property_throws_for_navigation()
ConfigurationSource.Explicit);
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(
- nameof(Order.Customer), nameof(Order), nameof(Order)),
+ CoreStrings.ConflictingPropertyOrNavigationWithKind(
+ nameof(Order.Customer), nameof(Order), "navigation"),
Assert.Throws(() => dependentEntityBuilder
.Property(Order.CustomerProperty, ConfigurationSource.Explicit)).Message);
}
@@ -2487,9 +2487,23 @@ private void VerifyOverrideMembers(
}
else
{
+ var conflictingKind = firstMemberType switch
+ {
+ MemberType.Property => "property",
+ MemberType.ComplexProperty => "complex property",
+ MemberType.ServiceProperty => "service property",
+ MemberType.Navigation => "navigation",
+ MemberType.SkipNavigation => "skip navigation",
+ _ => throw new InvalidOperationException()
+ };
+ var declaringTypeName = firstEntityTypeBuilder.Metadata.DisplayName();
+
Assert.Equal(
- CoreStrings.ConflictingPropertyOrNavigation(
- nameof(Order.Products), nameof(SpecialOrder), firstEntityTypeBuilder.Metadata.DisplayName()),
+ declaringTypeName == nameof(SpecialOrder)
+ ? CoreStrings.ConflictingPropertyOrNavigationWithKind(
+ nameof(Order.Products), nameof(SpecialOrder), conflictingKind)
+ : CoreStrings.ConflictingPropertyOrNavigationOnBaseType(
+ nameof(Order.Products), nameof(SpecialOrder), conflictingKind, declaringTypeName),
Assert.Throws(() => ConfigureMember(secondEntityTypeBuilder, secondMemberType, secondSource))
.Message);