/// <summary>
    ///     Called after an entity type is added to the model.
    /// </summary>
    /// <param name="entityTypeBuilder">The builder for the entity type.</param>
    /// <param name="context">Additional information associated with convention execution.</param>
    public virtual void ProcessEntityTypeAdded(
        IConventionEntityTypeBuilder entityTypeBuilder,
        IConventionContext <IConventionEntityTypeBuilder> context)
    {
        var entityType = entityTypeBuilder.Metadata;

        if (!entityType.HasSharedClrType)
        {
            return;
        }

        List <IConventionCheckConstraint>?constraintsToReattach = null;

        foreach (var checkConstraint in entityType.GetCheckConstraints())
        {
            if (checkConstraint.EntityType == entityType)
            {
                continue;
            }

            constraintsToReattach ??= new List <IConventionCheckConstraint>();

            constraintsToReattach.Add(checkConstraint);
        }

        if (constraintsToReattach == null)
        {
            return;
        }

        foreach (var checkConstraint in constraintsToReattach)
        {
            var removedCheckConstraint = entityType.RemoveCheckConstraint(checkConstraint.ModelName);
            if (removedCheckConstraint != null)
            {
                CheckConstraint.Attach(entityType, removedCheckConstraint);
            }
        }
    }
    /// <summary>
    ///     Called after the base type of an entity type changes.
    /// </summary>
    /// <param name="entityTypeBuilder">The builder for the entity type.</param>
    /// <param name="newBaseType">The new base entity type.</param>
    /// <param name="oldBaseType">The old base entity type.</param>
    /// <param name="context">Additional information associated with convention execution.</param>
    public virtual void ProcessEntityTypeBaseTypeChanged(
        IConventionEntityTypeBuilder entityTypeBuilder,
        IConventionEntityType?newBaseType,
        IConventionEntityType?oldBaseType,
        IConventionContext <IConventionEntityType> context)
    {
        var entityType = entityTypeBuilder.Metadata;

        if (newBaseType != null)
        {
            var configurationSource  = entityType.GetBaseTypeConfigurationSource();
            var baseCheckConstraints = newBaseType.GetCheckConstraints().ToDictionary(c => c.ModelName);
            List <IConventionCheckConstraint>?checkConstraintsToBeDetached = null;
            List <IConventionCheckConstraint>?checkConstraintsToBeRemoved  = null;
            foreach (var checkConstraint in entityType.GetDerivedTypesInclusive().SelectMany(et => et.GetDeclaredCheckConstraints()))
            {
                if (baseCheckConstraints.TryGetValue(checkConstraint.ModelName, out var baseCheckConstraint) &&
                    baseCheckConstraint.GetConfigurationSource().Overrides(checkConstraint.GetConfigurationSource()) &&
                    !AreCompatible(checkConstraint, baseCheckConstraint))
                {
                    if (baseCheckConstraint.GetConfigurationSource() == ConfigurationSource.Explicit &&
                        configurationSource == ConfigurationSource.Explicit &&
                        checkConstraint.GetConfigurationSource() == ConfigurationSource.Explicit)
                    {
                        throw new InvalidOperationException(
                                  RelationalStrings.DuplicateCheckConstraint(
                                      checkConstraint.ModelName,
                                      checkConstraint.EntityType.DisplayName(),
                                      baseCheckConstraint.EntityType.DisplayName()));
                    }

                    checkConstraintsToBeRemoved ??= new List <IConventionCheckConstraint>();

                    checkConstraintsToBeRemoved.Add(checkConstraint);
                    continue;
                }

                if (baseCheckConstraint != null)
                {
                    checkConstraintsToBeDetached ??= new List <IConventionCheckConstraint>();

                    checkConstraintsToBeDetached.Add(checkConstraint);
                }
            }

            if (checkConstraintsToBeRemoved != null)
            {
                foreach (var checkConstraintToBeRemoved in checkConstraintsToBeRemoved)
                {
                    checkConstraintToBeRemoved.EntityType.RemoveCheckConstraint(checkConstraintToBeRemoved.ModelName);
                }
            }

            if (checkConstraintsToBeDetached != null)
            {
                foreach (var checkConstraintToBeDetached in checkConstraintsToBeDetached)
                {
                    var baseCheckConstraint = baseCheckConstraints[checkConstraintToBeDetached.ModelName];
                    CheckConstraint.Attach(checkConstraintToBeDetached, baseCheckConstraint);

                    checkConstraintToBeDetached.EntityType.RemoveCheckConstraint(checkConstraintToBeDetached.ModelName);
                }
            }
        }
    }