/// <summary>
 ///     Compares this <see cref="RelationalTypeMappingInfo" /> to another to check if they represent the same mapping.
 /// </summary>
 /// <param name="other"> The other object. </param>
 /// <returns> <c>True</c> if they represent the same mapping; <c>false</c> otherwise. </returns>
 protected virtual bool Equals([NotNull] RelationalTypeMappingInfo other)
 => Equals((TypeMappingInfo)other) &&
 IsFixedLength == other.IsFixedLength &&
 StoreTypeName == other.StoreTypeName;
        /// <summary>
        ///     Clones the type mapping to update the name with size, precision,
        ///     and scale updated in the type name, as is common for some database
        ///     providers.
        /// </summary>
        /// <param name="mapping"> The mapping. </param>
        /// <param name="mappingInfo"> The mapping info containing the facets to use. </param>
        /// <returns> The cloned mapping, or the original mapping if no clone was needed. </returns>
        public static RelationalTypeMapping CloneWithFacetedName(
            [NotNull] this RelationalTypeMapping mapping,
            [NotNull] RelationalTypeMappingInfo mappingInfo)
        {
            Check.NotNull(mapping, nameof(mapping));
            Check.NotNull(mappingInfo, nameof(mappingInfo));

            var clone = false;

            var storeTypeName = mappingInfo.StoreTypeName;

            if (storeTypeName != null &&
                !storeTypeName.Equals(mapping.StoreType, StringComparison.Ordinal))
            {
                clone = true;
            }
            else
            {
                storeTypeName = mapping.StoreType;
            }

            var hints = mappingInfo.ValueConverterInfo?.MappingHints;

            var size = mapping.Size == -1 ? -1 : (int?)null;

            if (size != -1)
            {
                size = mappingInfo.Size
                       ?? mapping.Size
                       ?? hints?.Size;

                if (size != null &&
                    hints?.SizeFunction != null)
                {
                    size = hints.Value.SizeFunction(size.Value);
                }

                if (size != mapping.Size)
                {
                    var typeNameBase = GetTypeNameBase(mappingInfo, storeTypeName, out var isMax);
                    if (!mappingInfo.StoreTypeNameSizeIsMax &&
                        !isMax)
                    {
                        storeTypeName = typeNameBase + "(" + size + ")";
                    }

                    clone = true;
                }
            }

            if (mappingInfo.Precision != null &&
                mappingInfo.Scale != null)
            {
                storeTypeName = GetTypeNameBase(mappingInfo, storeTypeName, out var _)
                                + "(" + mappingInfo.Precision + "," + mappingInfo.Scale + ")";
                clone = true;
            }

            if (clone)
            {
                mapping = mapping.Clone(storeTypeName, size);
            }

            return(mapping);
        }
 /// <summary>
 ///     Compares this <see cref="RelationalTypeMappingInfo" /> to another to check if they represent the same mapping.
 /// </summary>
 /// <param name="other"> The other object. </param>
 /// <returns> <c>True</c> if they represent the same mapping; <c>false</c> otherwise. </returns>
 public bool Equals(RelationalTypeMappingInfo other)
 => _coreTypeMappingInfo.Equals(other._coreTypeMappingInfo) &&
 IsFixedLength == other.IsFixedLength &&
 StoreTypeName == other.StoreTypeName;
 /// <summary>
 ///     <para>
 ///         Overridden by relational database providers to find a type mapping for the given info.
 ///     </para>
 ///     <para>
 ///         The mapping info is populated with as much information about the required type mapping as
 ///         is available. Use all the information necessary to create the best mapping. Return <c>null</c>
 ///         if no mapping is available.
 ///     </para>
 /// </summary>
 /// <param name="mappingInfo"> The mapping info to use to create the mapping. </param>
 /// <returns> The type mapping, or <c>null</c> if none could be found. </returns>
 protected abstract RelationalTypeMapping FindMapping([NotNull] RelationalTypeMappingInfo mappingInfo);