private bool TryFindMatchingProperties( IConventionForeignKey foreignKey, string baseName, bool onDependent, bool matchPk, out IReadOnlyList <IConventionProperty>?match) { match = null; var dependentEntityType = onDependent ? foreignKey.DeclaringEntityType : foreignKey.PrincipalEntityType; var principalEntityType = onDependent ? foreignKey.PrincipalEntityType : foreignKey.DeclaringEntityType; var propertiesToReference = onDependent ? foreignKey.PrincipalKey.Properties : foreignKey.DeclaringEntityType.FindPrimaryKey()?.Properties; if (propertiesToReference == null) { return(false); } var foreignKeyProperties = new IConventionProperty[propertiesToReference.Count]; var matchFound = true; for (var i = 0; i < propertiesToReference.Count; i++) { var referencedProperty = propertiesToReference[i]; var property = TryGetProperty( dependentEntityType, baseName, referencedProperty.Name); if (property == null) { matchFound = false; continue; } foreignKeyProperties[i] = property; } if (!matchFound && propertiesToReference.Count == 1 && baseName.Length > 0) { var property = TryGetProperty( dependentEntityType, baseName, "Id"); if (property != null) { foreignKeyProperties[0] = property; matchFound = true; } } if (!matchFound) { return(false); } if (!ForeignKey.AreCompatible( propertiesToReference, foreignKeyProperties, principalEntityType, dependentEntityType, shouldThrow: false)) { if (propertiesToReference.All( p => !p.IsImplicitlyCreated() || p.GetConfigurationSource().Overrides(ConfigurationSource.DataAnnotation))) { var dependentNavigationSpec = onDependent ? foreignKey.DependentToPrincipal?.Name : foreignKey.PrincipalToDependent?.Name; dependentNavigationSpec = dependentEntityType.DisplayName() + (string.IsNullOrEmpty(dependentNavigationSpec) ? string.Empty : "." + dependentNavigationSpec); var principalNavigationSpec = onDependent ? foreignKey.PrincipalToDependent?.Name : foreignKey.DependentToPrincipal?.Name; principalNavigationSpec = principalEntityType.DisplayName() + (string.IsNullOrEmpty(principalNavigationSpec) ? string.Empty : "." + principalNavigationSpec); Dependencies.Logger.IncompatibleMatchingForeignKeyProperties( dependentNavigationSpec, principalNavigationSpec, foreignKeyProperties, propertiesToReference); } // Stop searching if match found, but is incompatible return(true); } foreach (var key in dependentEntityType.GetKeys()) { var isKeyContainedInForeignKey = true; // ReSharper disable once LoopCanBeConvertedToQuery // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < key.Properties.Count; i++) { if (!foreignKeyProperties.Contains(key.Properties[i])) { isKeyContainedInForeignKey = false; break; } } if (isKeyContainedInForeignKey && (!foreignKey.IsUnique || (key.IsPrimaryKey() && !matchPk))) { // Stop searching if match found, but is incompatible return(true); } } match = foreignKeyProperties; return(true); }