public virtual InternalRelationshipBuilder Apply(InternalRelationshipBuilder relationshipBuilder) { var foreignKey = relationshipBuilder.Metadata; if (!foreignKey.Properties.All(fk => fk.IsShadowProperty)) { return(relationshipBuilder); } var foreignKeyProperties = FindCandidateForeignKeyProperties( relationshipBuilder.Metadata, onDependent: true); if (foreignKey.IsUnique && !foreignKey.IsSelfPrimaryKeyReferencing()) { var candidatePropertiesOnPrincipal = FindCandidateForeignKeyProperties( relationshipBuilder.Metadata, onDependent: false); if (ShouldInvert(relationshipBuilder.Metadata, foreignKeyProperties, candidatePropertiesOnPrincipal) && relationshipBuilder.CanInvert(candidatePropertiesOnPrincipal, ConfigurationSource.Convention)) { relationshipBuilder = relationshipBuilder.DependentEntityType(relationshipBuilder.Metadata.PrincipalEntityType, ConfigurationSource.Convention); if (candidatePropertiesOnPrincipal != null) { relationshipBuilder = relationshipBuilder.HasForeignKey( candidatePropertiesOnPrincipal, ConfigurationSource.Convention); } Debug.Assert(relationshipBuilder != null); return(relationshipBuilder); } if (foreignKeyProperties == null) { foreignKeyProperties = GetCompatiblePrimaryKeyProperties( relationshipBuilder.Metadata.DeclaringEntityType, relationshipBuilder.Metadata.PrincipalEntityType, relationshipBuilder.Metadata.PrincipalKey.Properties); } } if ((foreignKeyProperties == null) || (relationshipBuilder.Metadata.DeclaringEntityType.FindForeignKey(foreignKeyProperties, foreignKey.PrincipalKey, foreignKey.PrincipalEntityType) != null)) { return(relationshipBuilder); } var newRelationshipBuilder = relationshipBuilder.HasForeignKey(foreignKeyProperties, ConfigurationSource.Convention); if (newRelationshipBuilder != null) { return(newRelationshipBuilder); } return(relationshipBuilder); }
public virtual InternalRelationshipBuilder Apply(InternalRelationshipBuilder relationshipBuilder) { var foreignKey = (IForeignKey)relationshipBuilder.Metadata; if (!foreignKey.Properties.All(fk => fk.IsShadowProperty)) { return relationshipBuilder; } var foreignKeyProperties = FindCandidateForeignKeyProperties( relationshipBuilder.Metadata, onDependent: true); if (foreignKey.IsUnique && !foreignKey.IsSelfPrimaryKeyReferencing()) { var candidatePropertiesOnPrincipal = FindCandidateForeignKeyProperties( relationshipBuilder.Metadata, onDependent: false); if (ShouldInvert(relationshipBuilder.Metadata, foreignKeyProperties, candidatePropertiesOnPrincipal) && relationshipBuilder.CanInvert(candidatePropertiesOnPrincipal, ConfigurationSource.Convention)) { relationshipBuilder = relationshipBuilder.DependentEntityType(relationshipBuilder.Metadata.PrincipalEntityType, ConfigurationSource.Convention); if (candidatePropertiesOnPrincipal != null) { relationshipBuilder = relationshipBuilder.HasForeignKey( candidatePropertiesOnPrincipal, ConfigurationSource.Convention); } Debug.Assert(relationshipBuilder != null); return relationshipBuilder; } if (foreignKeyProperties == null) { foreignKeyProperties = GetCompatiblePrimaryKeyProperties( relationshipBuilder.Metadata.DeclaringEntityType, relationshipBuilder.Metadata.PrincipalEntityType, relationshipBuilder.Metadata.PrincipalKey.Properties); } } if (foreignKeyProperties == null || relationshipBuilder.Metadata.DeclaringEntityType.FindForeignKey(foreignKeyProperties, foreignKey.PrincipalKey, foreignKey.PrincipalEntityType) != null) { return relationshipBuilder; } var newRelationshipBuilder = relationshipBuilder.HasForeignKey(foreignKeyProperties, ConfigurationSource.Convention); if (newRelationshipBuilder != null) { return newRelationshipBuilder; } return relationshipBuilder; }
public virtual InternalRelationshipBuilder Apply(InternalRelationshipBuilder relationshipBuilder) { var foreignKey = relationshipBuilder.Metadata; if (!foreignKey.Properties.All(fk => fk.IsShadowProperty)) { return(relationshipBuilder); } var foreignKeyProperties = FindCandidateForeignKeyProperties( foreignKey, onDependent: true); if (foreignKey.IsUnique && !foreignKey.IsSelfPrimaryKeyReferencing()) { var candidatePropertiesOnPrincipal = FindCandidateForeignKeyProperties( foreignKey, onDependent: false); if (candidatePropertiesOnPrincipal != null) { if ((foreignKeyProperties == null) && relationshipBuilder.CanInvert(candidatePropertiesOnPrincipal, ConfigurationSource.Convention)) { // Invert only if principal side has matching property & dependent does not have relationshipBuilder = relationshipBuilder .DependentEntityType(foreignKey.PrincipalEntityType, ConfigurationSource.Convention) .HasForeignKey(candidatePropertiesOnPrincipal, ConfigurationSource.Convention); Debug.Assert(relationshipBuilder != null); return(relationshipBuilder); } // Return if both sides have matching property return(relationshipBuilder); } // Only match with PK if the principal end is set if ((!ConfigurationSource.Convention.Overrides(foreignKey.GetPrincipalEndConfigurationSource()) || !ConfigurationSource.Convention.Overrides(foreignKey.GetPrincipalKeyConfigurationSource())) && (foreignKeyProperties == null)) { foreignKeyProperties = GetCompatiblePrimaryKeyProperties( foreignKey.DeclaringEntityType, foreignKey.PrincipalEntityType, foreignKey.PrincipalKey.Properties); } } else if ((foreignKey.DependentToPrincipal != null) && !foreignKey.DependentToPrincipal.IsCollection() && (foreignKey.PrincipalToDependent == null)) { // Single reference navigation which can be converted to one to one var candidatePropertiesOnPrincipal = FindCandidateForeignKeyProperties( foreignKey, onDependent: false); if (candidatePropertiesOnPrincipal != null) { if ((foreignKeyProperties == null) && relationshipBuilder.CanInvert(candidatePropertiesOnPrincipal, ConfigurationSource.Convention)) { // Invert and set one to one if principal side has matching property & dependent side does not have relationshipBuilder = relationshipBuilder .DependentEntityType(foreignKey.PrincipalEntityType, ConfigurationSource.Convention) .IsUnique(true, ConfigurationSource.Convention) .HasForeignKey(candidatePropertiesOnPrincipal, ConfigurationSource.Convention); Debug.Assert(relationshipBuilder != null); return(relationshipBuilder); } } } if ((foreignKeyProperties == null) || (foreignKey.DeclaringEntityType.FindForeignKey(foreignKeyProperties, foreignKey.PrincipalKey, foreignKey.PrincipalEntityType) != null)) { return(relationshipBuilder); } var newRelationshipBuilder = relationshipBuilder.HasForeignKey(foreignKeyProperties, ConfigurationSource.Convention); if (newRelationshipBuilder != null) { return(newRelationshipBuilder); } return(relationshipBuilder); }
public virtual InternalRelationshipBuilder Apply(InternalRelationshipBuilder relationshipBuilder) { Check.NotNull(relationshipBuilder, nameof(relationshipBuilder)); var foreignKey = relationshipBuilder.Metadata; var fkPropertyOnPrincipal = FindForeignKeyAttributeOnProperty(foreignKey.PrincipalEntityType, foreignKey.PrincipalToDependent?.Name); var fkPropertyOnDependent = FindForeignKeyAttributeOnProperty(foreignKey.DeclaringEntityType, foreignKey.DependentToPrincipal?.Name); if (!string.IsNullOrEmpty(fkPropertyOnDependent) && !string.IsNullOrEmpty(fkPropertyOnPrincipal)) { // TODO: Log Error that unable to determine principal end based on foreign key attributes on properties SplitNavigationsInSeparateRelationships(relationshipBuilder); return(null); } var fkPropertiesOnPrincipalToDependent = FindCandidateDependentPropertiesThroughNavigation(relationshipBuilder, pointsToPrincipal: false); var fkPropertiesOnDependentToPrincipal = FindCandidateDependentPropertiesThroughNavigation(relationshipBuilder, pointsToPrincipal: true); if (fkPropertiesOnDependentToPrincipal != null && fkPropertiesOnPrincipalToDependent != null && !fkPropertiesOnDependentToPrincipal.SequenceEqual(fkPropertiesOnPrincipalToDependent)) { // TODO: Log error that foreign key properties on both navigations do not match SplitNavigationsInSeparateRelationships(relationshipBuilder); return(null); } var fkPropertiesOnNavigation = fkPropertiesOnDependentToPrincipal ?? fkPropertiesOnPrincipalToDependent; InternalRelationshipBuilder newRelationshipBuilder = null; if (fkPropertiesOnNavigation == null || fkPropertiesOnNavigation.Count == 0) { if (fkPropertyOnDependent == null && fkPropertyOnPrincipal == null) { return(relationshipBuilder); } if (fkPropertyOnDependent != null) { newRelationshipBuilder = relationshipBuilder.HasForeignKey(new List <string> { fkPropertyOnDependent }, ConfigurationSource.DataAnnotation); } else { newRelationshipBuilder = relationshipBuilder .DependentEntityType(foreignKey.PrincipalEntityType, ConfigurationSource.DataAnnotation) ?.HasForeignKey(new List <string> { fkPropertyOnPrincipal }, ConfigurationSource.DataAnnotation); } } else { if (fkPropertyOnDependent == null && fkPropertyOnPrincipal == null) { if (fkPropertiesOnNavigation.All(p => foreignKey.DeclaringEntityType.FindProperty(p) != null) || fkPropertiesOnNavigation.Any(p => foreignKey.PrincipalEntityType.FindProperty(p) == null)) { newRelationshipBuilder = relationshipBuilder.HasForeignKey(fkPropertiesOnNavigation, ConfigurationSource.DataAnnotation); } else { newRelationshipBuilder = relationshipBuilder .DependentEntityType(foreignKey.PrincipalEntityType, ConfigurationSource.DataAnnotation) ?.HasForeignKey(fkPropertiesOnNavigation, ConfigurationSource.DataAnnotation); } } else { if (fkPropertiesOnNavigation.Count != 1 || !string.Equals(fkPropertiesOnNavigation.First(), fkPropertyOnDependent ?? fkPropertyOnPrincipal)) { // TODO: Log error that mismatch in foreignKey Attribute on navigation and property SplitNavigationsInSeparateRelationships(relationshipBuilder); return(null); } if (fkPropertyOnDependent != null) { newRelationshipBuilder = relationshipBuilder.HasForeignKey(fkPropertiesOnNavigation, ConfigurationSource.DataAnnotation); } else { newRelationshipBuilder = relationshipBuilder .DependentEntityType(foreignKey.PrincipalEntityType, ConfigurationSource.DataAnnotation) ?.HasForeignKey(fkPropertiesOnNavigation, ConfigurationSource.DataAnnotation); } } } return(newRelationshipBuilder ?? relationshipBuilder); }
public virtual InternalRelationshipBuilder Apply(InternalRelationshipBuilder relationshipBuilder) { Check.NotNull(relationshipBuilder, nameof(relationshipBuilder)); var foreignKey = relationshipBuilder.Metadata; var fkPropertyOnPrincipal = FindForeignKeyAttributeOnProperty(foreignKey.PrincipalEntityType, foreignKey.PrincipalToDependent?.Name); var fkPropertyOnDependent = FindForeignKeyAttributeOnProperty(foreignKey.DeclaringEntityType, foreignKey.DependentToPrincipal?.Name); if (!string.IsNullOrEmpty(fkPropertyOnDependent) && !string.IsNullOrEmpty(fkPropertyOnPrincipal)) { // TODO: Log Error that unable to determine principal end based on foreign key attributes on properties SplitNavigationsInSeparateRelationships(relationshipBuilder); return null; } var fkPropertiesOnPrincipalToDependent = FindCandidateDependentPropertiesThroughNavigation(relationshipBuilder, pointsToPrincipal: false); var fkPropertiesOnDependentToPrincipal = FindCandidateDependentPropertiesThroughNavigation(relationshipBuilder, pointsToPrincipal: true); if (fkPropertiesOnDependentToPrincipal != null && fkPropertiesOnPrincipalToDependent != null && !fkPropertiesOnDependentToPrincipal.SequenceEqual(fkPropertiesOnPrincipalToDependent)) { // TODO: Log error that foreign key properties on both navigations do not match SplitNavigationsInSeparateRelationships(relationshipBuilder); return null; } var fkPropertiesOnNavigation = fkPropertiesOnDependentToPrincipal ?? fkPropertiesOnPrincipalToDependent; InternalRelationshipBuilder newRelationshipBuilder = null; if (fkPropertiesOnNavigation == null || fkPropertiesOnNavigation.Count == 0) { if (fkPropertyOnDependent == null && fkPropertyOnPrincipal == null) { return relationshipBuilder; } if (fkPropertyOnDependent != null) { newRelationshipBuilder = relationshipBuilder.HasForeignKey(new List<string> { fkPropertyOnDependent }, ConfigurationSource.DataAnnotation); } else { newRelationshipBuilder = relationshipBuilder .DependentEntityType(foreignKey.PrincipalEntityType, ConfigurationSource.DataAnnotation) ?.HasForeignKey(new List<string> { fkPropertyOnPrincipal }, ConfigurationSource.DataAnnotation); } } else { if (fkPropertyOnDependent == null && fkPropertyOnPrincipal == null) { if (fkPropertiesOnNavigation.All(p => foreignKey.DeclaringEntityType.FindProperty(p) != null) || fkPropertiesOnNavigation.Any(p => foreignKey.PrincipalEntityType.FindProperty(p) == null)) { newRelationshipBuilder = relationshipBuilder.HasForeignKey(fkPropertiesOnNavigation, ConfigurationSource.DataAnnotation); } else { newRelationshipBuilder = relationshipBuilder .DependentEntityType(foreignKey.PrincipalEntityType, ConfigurationSource.DataAnnotation) ?.HasForeignKey(fkPropertiesOnNavigation, ConfigurationSource.DataAnnotation); } } else { if (fkPropertiesOnNavigation.Count != 1 || !string.Equals(fkPropertiesOnNavigation.First(), fkPropertyOnDependent ?? fkPropertyOnPrincipal)) { // TODO: Log error that mismatch in foreignKey Attribute on navigation and property SplitNavigationsInSeparateRelationships(relationshipBuilder); return null; } if (fkPropertyOnDependent != null) { newRelationshipBuilder = relationshipBuilder.HasForeignKey(fkPropertiesOnNavigation, ConfigurationSource.DataAnnotation); } else { newRelationshipBuilder = relationshipBuilder .DependentEntityType(foreignKey.PrincipalEntityType, ConfigurationSource.DataAnnotation) ?.HasForeignKey(fkPropertiesOnNavigation, ConfigurationSource.DataAnnotation); } } } return newRelationshipBuilder ?? relationshipBuilder; }