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); }