public virtual ConfigurationSource?RemoveRelationship([NotNull] ForeignKey foreignKey, ConfigurationSource configurationSource)
        {
            if (foreignKey.EntityType != Metadata)
            {
                return(ModelBuilder.Entity(foreignKey.EntityType.Name, ConfigurationSource.Convention)
                       .RemoveRelationship(foreignKey, configurationSource));
            }

            var removedConfigurationSource = _relationshipBuilders.Value.Remove(foreignKey, configurationSource);

            if (removedConfigurationSource == null)
            {
                return(null);
            }

            var principalEntityTypeBuilder = ModelBuilder.Entity(foreignKey.PrincipalEntityType.Name, ConfigurationSource.Convention);

            var navigationToDependent = foreignKey.GetNavigationToDependent();

            navigationToDependent?.EntityType.RemoveNavigation(navigationToDependent);

            var navigationToPrincipal = foreignKey.GetNavigationToPrincipal();

            navigationToPrincipal?.EntityType.RemoveNavigation(navigationToPrincipal);

            Metadata.RemoveForeignKey(foreignKey);
            ModelBuilder.ConventionDispatcher.OnForeignKeyRemoved(this, foreignKey);
            RemoveShadowPropertiesIfUnused(foreignKey.Properties);
            principalEntityTypeBuilder.RemoveKeyIfUnused(foreignKey.PrincipalKey);

            return(removedConfigurationSource);
        }
Esempio n. 2
0
        public virtual bool RemoveRelationship([NotNull] ForeignKey foreignKey, ConfigurationSource configurationSource)
        {
            if (foreignKey.EntityType != Metadata)
            {
                return(ModelBuilder.Entity(foreignKey.EntityType.Name, ConfigurationSource.Convention)
                       .RemoveRelationship(foreignKey, configurationSource));
            }

            if (!_relationshipBuilders.Value.Remove(foreignKey, configurationSource))
            {
                return(false);
            }

            var navigationToDependent = foreignKey.GetNavigationToDependent();

            navigationToDependent?.EntityType.RemoveNavigation(navigationToDependent);

            var navigationToPrincipal = foreignKey.GetNavigationToPrincipal();

            navigationToPrincipal?.EntityType.RemoveNavigation(navigationToPrincipal);

            Metadata.RemoveForeignKey(foreignKey);

            RemoveShadowPropertiesIfUnused(foreignKey.Properties, configurationSource);

            return(true);
        }
Esempio n. 3
0
 private void RemoveForeignKeyIfUnused(ForeignKey foreignKey, ConfigurationSource configurationSource)
 {
     if (foreignKey.GetNavigationToDependent() == null &&
         foreignKey.GetNavigationToPrincipal() == null)
     {
         RemoveRelationship(foreignKey, configurationSource);
     }
 }
Esempio n. 4
0
        private bool Navigation(
            [CanBeNull] string navigationName,
            [NotNull] ForeignKey foreignKey,
            bool pointsToPrincipal,
            ConfigurationSource configurationSource,
            bool canOverrideSameSource)
        {
            Check.NotNull(foreignKey, "foreignKey");

            var navigation = pointsToPrincipal
                ? foreignKey.GetNavigationToPrincipal()
                : foreignKey.GetNavigationToDependent();

            var fkOwner = foreignKey.EntityType == Metadata
                ? this
                : ModelBuilder.Entity(foreignKey.EntityType.Name, ConfigurationSource.Convention);

            if (navigationName == navigation?.Name)
            {
                fkOwner._relationshipBuilders.Value.UpdateConfigurationSource(foreignKey, configurationSource);
                return(true);
            }

            if (!CanSetNavigation(navigationName, foreignKey, pointsToPrincipal, configurationSource, canOverrideSameSource))
            {
                return(false);
            }

            navigation?.EntityType.RemoveNavigation(navigation);

            var conflictingNavigation = navigationName == null
                ? null
                : Metadata.TryGetNavigation(navigationName);

            if (conflictingNavigation != null)
            {
                var removed = RemoveRelationship(conflictingNavigation.ForeignKey, configurationSource);
                Debug.Assert(removed);
            }

            if (navigationName != null)
            {
                if (_ignoredProperties.HasValue)
                {
                    _ignoredProperties.Value.Remove(navigationName);
                }

                fkOwner._relationshipBuilders.Value.UpdateConfigurationSource(foreignKey, configurationSource);
                Metadata.AddNavigation(navigationName, foreignKey, pointsToPrincipal);
                return(true);
            }

            return(true);
        }
        private bool ShouldFlip(ForeignKey foreignKey, IReadOnlyList<Property> currentDependentCandidateProperties)
        {
            var currentPrincipalCandidateProperties = GetCandidateForeignKeyProperties(foreignKey, onDependent: false);
            
            if (currentDependentCandidateProperties != null
                && currentPrincipalCandidateProperties == null)
            {
                return false;
            }

            if (currentDependentCandidateProperties == null
                && currentPrincipalCandidateProperties != null)
            {
                return true;
            }

            var navigationToPrincipal = foreignKey.GetNavigationToPrincipal();
            var navigationToDependent = foreignKey.GetNavigationToDependent();

            if (navigationToPrincipal == null
                && navigationToDependent != null)
            {
                return false;
            }

            if (navigationToPrincipal != null
                && navigationToDependent == null)
            {
                return true;
            }

            var model = foreignKey.EntityType.Model;
            var principalPk = foreignKey.PrincipalEntityType.FindPrimaryKey();
            var principalPkReferenceThreshold = foreignKey.PrincipalKey == principalPk? 1 : 0;
            var isPrincipalKeyReferenced = principalPk != null && model.GetReferencingForeignKeys(principalPk).Count > principalPkReferenceThreshold;
            var dependentPk = foreignKey.EntityType.FindPrimaryKey();
            var isDependentPrimaryKeyReferenced = dependentPk != null && model.GetReferencingForeignKeys(dependentPk).Count > 0;

            if (isPrincipalKeyReferenced
                && !isDependentPrimaryKeyReferenced)
            {
                return false;
            }

            if (!isPrincipalKeyReferenced
                && isDependentPrimaryKeyReferenced)
            {
                return true;
            }
            
            return StringComparer.Ordinal.Compare(foreignKey.PrincipalEntityType.Name, foreignKey.EntityType.Name) > 0;
        }
        private RelationshipSnapshot DetachRelationship([NotNull] ForeignKey foreignKey, ConfigurationSource configurationSource)
        {
            var navigationToPrincipalName = foreignKey.GetNavigationToPrincipal()?.Name;
            var navigationToDependentName = foreignKey.GetNavigationToDependent()?.Name;
            var relationship = Relationship(foreignKey, true, ConfigurationSource.Convention);
            var relationshipConfigurationSource = RemoveRelationship(foreignKey, configurationSource);

            if (relationshipConfigurationSource == null)
            {
                return(null);
            }

            return(new RelationshipSnapshot(relationship, navigationToPrincipalName, navigationToDependentName, relationshipConfigurationSource.Value));
        }
Esempio n. 7
0
        private bool CanSetNavigation(
            string navigationName,
            ForeignKey foreignKey,
            bool pointsToPrincipal,
            ConfigurationSource configurationSource,
            bool canOverrideSameSource)
        {
            var navigation = pointsToPrincipal
                ? foreignKey.GetNavigationToPrincipal()
                : foreignKey.GetNavigationToDependent();

            if (navigationName == navigation?.Name)
            {
                return(true);
            }

            if (!CanRemove(foreignKey, configurationSource, canOverrideSameSource))
            {
                return(false);
            }

            var conflictingNavigation = navigationName == null
                ? null
                : Metadata.TryGetNavigation(navigationName);

            if (conflictingNavigation != null &&
                !CanRemove(conflictingNavigation.ForeignKey, configurationSource, canOverrideSameSource))
            {
                return(false);
            }

            if (navigationName != null &&
                !CanAdd(navigationName, isNavigation: true, configurationSource: configurationSource))
            {
                return(false);
            }
            return(true);
        }
        private IReadOnlyList<Property> GetCandidateForeignKeyProperties(ForeignKey foreignKey, bool onDependent)
        {
            var baseNames = new List<string>();
            var navigation = onDependent
                ? foreignKey.GetNavigationToPrincipal()
                : foreignKey.GetNavigationToDependent();
            if (navigation != null)
            {
                baseNames.Add(navigation.Name);
            }

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

            baseNames.Add("");

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