private IReadOnlyList<Property> FindCandidateForeignKeyProperties(ForeignKey foreignKey, bool onDependent)
        {
            var baseNames = new List<string>();
            var navigation = onDependent
                ? foreignKey.DependentToPrincipal
                : foreignKey.PrincipalToDependent;
            if (navigation != null)
            {
                baseNames.Add(navigation.Name);
            }

            var entityTypeToReference = onDependent
                ? foreignKey.PrincipalEntityType
                : foreignKey.DeclaringEntityType;
            baseNames.Add(entityTypeToReference.DisplayName());

            baseNames.Add("");

            foreach (var baseName in baseNames)
            {
                var match = FindMatchingProperties(foreignKey, baseName, onDependent);
                if (match != null)
                {
                    return match;
                }
            }

            return null;
        }
        private IReadOnlyList<Property> FindMatchingProperties(
            ForeignKey foreignKey, string baseName, bool onDependent)
        {
            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 null;
            }

            var foreignKeyProperties = new List<Property>();
            foreach (IProperty referencedProperty in propertiesToReference)
            {
                var property = TryGetProperty(dependentEntityType,
                    baseName + referencedProperty.Name,
                    referencedProperty.ClrType.UnwrapNullableType());

                if (property != null)
                {
                    foreignKeyProperties.Add(property);
                }
            }

            if ((propertiesToReference.Count == 1)
                && (foreignKeyProperties.Count == 0))
            {
                var property = TryGetProperty(dependentEntityType,
                    baseName + "Id",
                    propertiesToReference.Single().ClrType.UnwrapNullableType());

                if (property != null)
                {
                    foreignKeyProperties.Add(property);
                }
            }

            if (foreignKeyProperties.Count < propertiesToReference.Count)
            {
                return null;
            }

            if (!ForeignKey.AreCompatible(
                propertiesToReference,
                foreignKeyProperties,
                principalEntityType,
                dependentEntityType,
                shouldThrow: false))
            {
                return null;
            }

            var primaryKey = dependentEntityType.FindPrimaryKey();
            if (primaryKey != null)
            {
                if (foreignKeyProperties.All(property => primaryKey.Properties.Contains(property)))
                {
                    return null;
                }
            }

            // Don't match with only Id since it is ambiguous. PK in dependent entity used as FK is matched elsewhere
            if ((foreignKeyProperties.Count == 1)
                && (foreignKeyProperties.Single().Name == "Id"))
            {
                return null;
            }

            return foreignKeyProperties;
        }
 public virtual void Apply(InternalEntityTypeBuilder entityTypeBuilder, ForeignKey foreignKey)
 {
     var properties = foreignKey.Properties;
     SetValueGeneration(properties.Where(property => property.IsKey()));
     SetIdentity(properties, entityTypeBuilder.Metadata);
 }