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;
        }
Example #3
0
        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);
        }