/// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual bool Apply(InternalModelBuilder modelBuilder, EntityType type)
        {
            if (type.HasDefiningNavigation())
            {
                var entityTypes     = modelBuilder.Metadata.GetEntityTypes(type.Name);
                var otherEntityType = entityTypes.FirstOrDefault();
                if (otherEntityType?.HasDefiningNavigation() == true)
                {
                    var ownership = otherEntityType.FindOwnership();
                    if (ownership != null &&
                        entityTypes.Count == 1)
                    {
                        using (modelBuilder.Metadata.ConventionDispatcher.StartBatch())
                        {
                            var detachedRelationship = InternalEntityTypeBuilder.DetachRelationship(ownership);

                            var weakSnapshot = InternalEntityTypeBuilder.DetachAllMembers(otherEntityType);
                            modelBuilder.RemoveEntityType(otherEntityType, ConfigurationSource.Explicit);

                            detachedRelationship.WeakEntityTypeSnapshot = weakSnapshot;
                            detachedRelationship.Attach(ownership.PrincipalEntityType.Builder);
                        }
                    }
                }
            }

            return(true);
        }
        /// <summary>
        ///     Called after an entity type is removed from the model.
        /// </summary>
        /// <param name="modelBuilder"> The builder for the model. </param>
        /// <param name="entityType"> The removed entity type. </param>
        /// <param name="context"> Additional information associated with convention execution. </param>
        public virtual void ProcessEntityTypeRemoved(
            IConventionModelBuilder modelBuilder,
            IConventionEntityType entityType,
            IConventionContext <IConventionEntityType> context)
        {
            if (!entityType.HasDefiningNavigation())
            {
                return;
            }

            var entityTypes     = modelBuilder.Metadata.GetEntityTypes(entityType.Name);
            var otherEntityType = entityTypes.FirstOrDefault();

            if (otherEntityType?.HasDefiningNavigation() == true &&
                entityTypes.Count == 1 &&
                otherEntityType.FindOwnership() is ForeignKey ownership)
            {
                using (context.DelayConventions())
                {
                    InternalEntityTypeBuilder.DetachRelationship(ownership).Attach(ownership.PrincipalEntityType.Builder);
                }
            }
        }
        private InternalRelationshipBuilder ReuniquifyTemporaryProperties(ForeignKey foreignKey, bool force)
        {
            if (!force &&
                (foreignKey.GetForeignKeyPropertiesConfigurationSource() != null ||
                 !foreignKey.DeclaringEntityType.Builder.ShouldReuniquifyTemporaryProperties(
                     foreignKey.Properties,
                     foreignKey.PrincipalKey.Properties,
                     foreignKey.IsRequired && foreignKey.GetIsRequiredConfigurationSource().Overrides(ConfigurationSource.Convention),
                     GetPropertyBaseName(foreignKey))))
            {
                return(foreignKey.Builder);
            }

            var relationshipBuilder = foreignKey.Builder;

            using (var batch = foreignKey.DeclaringEntityType.Model.ConventionDispatcher.StartBatch())
            {
                var temporaryProperties = foreignKey.Properties.Where(
                    p => p.IsShadowProperty &&
                    ConfigurationSource.Convention.Overrides(p.GetConfigurationSource())).ToList();

                var keysToDetach = temporaryProperties.SelectMany(
                    p => p.GetContainingKeys()
                    .Where(k => ConfigurationSource.Convention.Overrides(k.GetConfigurationSource())))
                                   .Distinct().ToList();

                List <RelationshipSnapshot> detachedRelationships = null;
                foreach (var key in keysToDetach)
                {
                    foreach (var referencingForeignKey in key.GetReferencingForeignKeys().ToList())
                    {
                        if (detachedRelationships == null)
                        {
                            detachedRelationships = new List <RelationshipSnapshot>();
                        }

                        detachedRelationships.Add(InternalEntityTypeBuilder.DetachRelationship(referencingForeignKey));
                    }
                }

                var detachedKeys = InternalEntityTypeBuilder.DetachKeys(keysToDetach);

                var detachedIndexes = InternalEntityTypeBuilder.DetachIndexes(
                    temporaryProperties.SelectMany(p => p.GetContainingIndexes()).Distinct());

                relationshipBuilder = relationshipBuilder.HasForeignKey((IReadOnlyList <Property>)null, ConfigurationSource.Convention);

                if (detachedIndexes != null)
                {
                    foreach (var indexBuilderTuple in detachedIndexes)
                    {
                        indexBuilderTuple.Attach(indexBuilderTuple.Metadata.DeclaringEntityType.Builder);
                    }
                }

                if (detachedKeys != null)
                {
                    foreach (var detachedKeyTuple in detachedKeys)
                    {
                        detachedKeyTuple.Item1.Attach(foreignKey.DeclaringEntityType.RootType().Builder, detachedKeyTuple.Item2);
                    }
                }

                if (detachedRelationships != null)
                {
                    foreach (var detachedRelationship in detachedRelationships)
                    {
                        detachedRelationship.Attach();
                    }
                }

                return(batch.Run(relationshipBuilder));
            }
        }