Beispiel #1
0
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
        /// </summary>
        /// <param name="member"> The property or field for which mapping is needed. </param>
        public RelationalTypeMappingInfo([NotNull] MemberInfo member)
        {
            Check.NotNull(member, nameof(member));

            _coreTypeMappingInfo = new TypeMappingInfo(member);

            if (Attribute.IsDefined(member, typeof(ColumnAttribute), inherit: true))
            {
                var attribute = member.GetCustomAttributes <ColumnAttribute>(inherit: true).First();
                StoreTypeName     = attribute.TypeName;
                StoreTypeNameBase = ParseStoreTypeName(
                    attribute.TypeName, out _parsedSize, out _parsedPrecision, out _parsedScale, out _isMax);
            }
            else
            {
                StoreTypeName     = null;
                StoreTypeNameBase = null;
                _parsedSize       = null;
                _parsedPrecision  = null;
                _parsedScale      = null;
                _isMax            = false;
            }

            IsFixedLength = null;
        }
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
        /// </summary>
        /// <param name="member"> The property or field for which mapping is needed. </param>
        public RelationalTypeMappingInfo([NotNull] MemberInfo member)
        {
            Check.NotNull(member, nameof(member));

            _coreTypeMappingInfo = new TypeMappingInfo(member);

            var attribute = member.GetCustomAttributes <ColumnAttribute>(true)?.FirstOrDefault();

            if (attribute != null)
            {
                StoreTypeName     = attribute.TypeName;
                StoreTypeNameBase = ParseStoreTypeName(attribute.TypeName, out _parsedSize, out _parsedPrecision, out _parsedScale, out _isMax);
            }
            else
            {
                StoreTypeName     = null;
                StoreTypeNameBase = null;
                _parsedSize       = null;
                _parsedPrecision  = null;
                _parsedScale      = null;
                _isMax            = false;
            }

            IsFixedLength = false;
        }
Beispiel #3
0
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
        /// </summary>
        /// <param name="principals"> The principal property chain for the property for which mapping is needed. </param>
        public RelationalTypeMappingInfo([NotNull] IReadOnlyList <IProperty> principals)
        {
            _coreTypeMappingInfo = new TypeMappingInfo(principals);

            string storeTypeName = null;
            bool?  fixedLength   = null;

            for (var i = 0; i < principals.Count; i++)
            {
                var principal = principals[i];
                if (storeTypeName == null)
                {
                    var columnType = (string)principal[RelationalAnnotationNames.ColumnType];
                    if (columnType != null)
                    {
                        storeTypeName = columnType;
                    }
                }

                if (fixedLength == null)
                {
                    fixedLength = principal.Relational().IsFixedLength;
                }
            }

            IsFixedLength     = fixedLength;
            StoreTypeName     = storeTypeName;
            StoreTypeNameBase = ParseStoreTypeName(storeTypeName, out _parsedSize, out _parsedPrecision, out _parsedScale, out _isMax);
        }
Beispiel #4
0
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
        /// </summary>
        /// <param name="storeTypeName"> The provider-specific relational type name for which mapping is needed. </param>
        public RelationalTypeMappingInfo([NotNull] string storeTypeName)
        {
            Check.NotEmpty(storeTypeName, nameof(storeTypeName));

            _coreTypeMappingInfo = new TypeMappingInfo();
            IsFixedLength        = false;
            StoreTypeName        = storeTypeName;
            StoreTypeNameBase    = ParseStoreTypeName(storeTypeName, out _parsedSize, out _parsedPrecision, out _parsedScale, out _isMax);
        }
Beispiel #5
0
 /// <summary>
 ///     Compares this <see cref="TypeMappingInfo" /> 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] TypeMappingInfo other)
 => ClrType == other.ClrType &&
 MemberInfo == other.MemberInfo &&
 IsKeyOrIndex == other.IsKeyOrIndex &&
 Size == other.Size &&
 IsUnicode == other.IsUnicode &&
 IsRowVersion == other.IsRowVersion &&
 Precision == other.Precision &&
 Scale == other.Scale;
Beispiel #6
0
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
        /// </summary>
        /// <param name="storeTypeName"> The provider-specific relational type name for which mapping is needed. </param>
        public RelationalTypeMappingInfo([NotNull] string storeTypeName)
        {
            // Note: Empty string is allowed for store type name because SQLite
            Check.NotNull(storeTypeName, nameof(storeTypeName));

            _coreTypeMappingInfo = new TypeMappingInfo();
            StoreTypeName        = storeTypeName;
            StoreTypeNameBase    = ParseStoreTypeName(storeTypeName, out _parsedSize, out _parsedPrecision, out _parsedScale, out _isMax);
            IsFixedLength        = null;
        }
Beispiel #7
0
 /// <summary>
 ///     Compares this <see cref="TypeMappingInfo" /> 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(TypeMappingInfo other)
 => ClrType == other.ClrType &&
 _providerClrType == other._providerClrType &&
 _customConverter == other._customConverter &&
 IsKeyOrIndex == other.IsKeyOrIndex &&
 Size == other.Size &&
 IsUnicode == other.IsUnicode &&
 IsRowVersion == other.IsRowVersion &&
 Precision == other.Precision &&
 Scale == other.Scale;
 /// <summary>
 ///     Compares this <see cref="TypeMappingInfo" /> 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] TypeMappingInfo other)
 => ModelClrType == other.ModelClrType &&
 MemberInfo == other.MemberInfo &&
 ConfiguredProviderClrType == other.ConfiguredProviderClrType &&
 IsKeyOrIndex == other.IsKeyOrIndex &&
 Size == other.Size &&
 IsUnicode == other.IsUnicode &&
 IsRowVersion == other.IsRowVersion &&
 Precision == other.Precision &&
 Scale == other.Scale &&
 Equals(_customConverter, other._customConverter);
Beispiel #9
0
 /// <summary>
 ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
 /// </summary>
 /// <param name="type"> The CLR type in the model for which mapping is needed. </param>
 public RelationalTypeMappingInfo([NotNull] Type type)
 {
     _coreTypeMappingInfo = new TypeMappingInfo(type);
     StoreTypeName        = null;
     StoreTypeNameBase    = null;
     IsFixedLength        = null;
     _parsedSize          = null;
     _parsedPrecision     = null;
     _parsedScale         = null;
     _isMax = false;
 }
Beispiel #10
0
 /// <summary>
 ///     Compares this <see cref="TypeMappingInfo" /> 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 bool Equals(TypeMappingInfo other)
 => ModelClrType == other.ModelClrType &&
 StoreClrType == other.StoreClrType &&
 IsKeyOrIndex == other.IsKeyOrIndex &&
 Size == other.Size &&
 IsUnicode == other.IsUnicode &&
 IsRowVersion == other.IsRowVersion &&
 IsFixedLength == other.IsFixedLength &&
 Precision == other.Precision &&
 Scale == other.Scale &&
 Equals(_customConverter, other._customConverter);
 /// <summary>
 ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
 /// </summary>
 /// <param name="storeTypeName">The provider-specific relational type name for which mapping is needed.</param>
 /// <param name="storeTypeNameBase">The provider-specific relational type name, with any facets removed.</param>
 /// <param name="unicode">Specifies Unicode or ANSI mapping, or <see langword="null" /> for default.</param>
 /// <param name="size">Specifies a size for the mapping, or <see langword="null" /> for default.</param>
 /// <param name="precision">Specifies a precision for the mapping, or <see langword="null" /> for default.</param>
 /// <param name="scale">Specifies a scale for the mapping, or <see langword="null" /> for default.</param>
 public RelationalTypeMappingInfo(
     string storeTypeName,
     string storeTypeNameBase,
     bool?unicode,
     int?size,
     int?precision,
     int?scale)
 {
     // Note: Empty string is allowed for store type name because SQLite
     _coreTypeMappingInfo = new TypeMappingInfo(null, false, unicode, size, null, precision, scale);
     StoreTypeName        = storeTypeName;
     StoreTypeNameBase    = storeTypeNameBase;
     IsFixedLength        = null;
 }
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
        /// </summary>
        /// <param name="member">The property or field for which mapping is needed.</param>
        /// <param name="storeTypeName">The provider-specific relational type name for which mapping is needed.</param>
        /// <param name="storeTypeNameBase">The provider-specific relational type name, with any facets removed.</param>
        /// <param name="unicode">Specifies Unicode or ANSI mapping, or <see langword="null" /> for default.</param>
        /// <param name="size">Specifies a size for the mapping, or <see langword="null" /> for default.</param>
        /// <param name="precision">Specifies a precision for the mapping, or <see langword="null" /> for default.</param>
        /// <param name="scale">Specifies a scale for the mapping, or <see langword="null" /> for default.</param>
        public RelationalTypeMappingInfo(
            MemberInfo member,
            string?storeTypeName     = null,
            string?storeTypeNameBase = null,
            bool?unicode             = null,
            int?size      = null,
            int?precision = null,
            int?scale     = null)
        {
            _coreTypeMappingInfo = new TypeMappingInfo(member, unicode, size, precision, scale);

            StoreTypeName     = storeTypeName;
            StoreTypeNameBase = storeTypeNameBase;
            IsFixedLength     = null;
        }
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
        /// </summary>
        /// <param name="principals">The principal property chain for the property for which mapping is needed.</param>
        /// <param name="storeTypeName">The provider-specific relational type name for which mapping is needed.</param>
        /// <param name="storeTypeNameBase">The provider-specific relational type name, with any facets removed.</param>
        /// <param name="fallbackUnicode">
        ///     Specifies a fallback Specifies Unicode or ANSI mapping for the mapping, in case one isn't found at the core
        ///     level, or <see langword="null" /> for default.
        /// </param>
        /// <param name="fixedLength">Specifies a fixed length mapping, or <see langword="null" /> for default.</param>
        /// <param name="fallbackSize">
        ///     Specifies a fallback size for the mapping, in case one isn't found at the core level, or <see langword="null" /> for
        ///     default.
        /// </param>
        /// <param name="fallbackPrecision">
        ///     Specifies a fallback precision for the mapping, in case one isn't found at the core level, or <see langword="null" />
        ///     for default.
        /// </param>
        /// <param name="fallbackScale">
        ///     Specifies a fallback scale for the mapping, in case one isn't found at the core level, or <see langword="null" /> for
        ///     default.
        /// </param>
        public RelationalTypeMappingInfo(
            IReadOnlyList <IProperty> principals,
            string?storeTypeName     = null,
            string?storeTypeNameBase = null,
            bool?fallbackUnicode     = null,
            bool?fixedLength         = null,
            int?fallbackSize         = null,
            int?fallbackPrecision    = null,
            int?fallbackScale        = null)
        {
            _coreTypeMappingInfo = new TypeMappingInfo(principals, fallbackUnicode, fallbackSize, fallbackPrecision, fallbackScale);

            IsFixedLength     = fixedLength;
            StoreTypeName     = storeTypeName;
            StoreTypeNameBase = storeTypeNameBase;
        }
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
        /// </summary>
        /// <param name="member"> The property or field for which mapping is needed. </param>
        /// <param name="storeTypeName"> The provider-specific relational type name for which mapping is needed. </param>
        /// <param name="storeTypeNameBase"> The provider-specific relational type name, with any facets removed. </param>
        /// <param name="unicode"> Specifies Unicode or ANSI mapping, or <c>null</c> for default. </param>
        /// <param name="size"> Specifies a size for the mapping, or <c>null</c> for default. </param>
        /// <param name="precision"> Specifies a precision for the mapping, or <c>null</c> for default. </param>
        /// <param name="scale"> Specifies a scale for the mapping, or <c>null</c> for default. </param>
        public RelationalTypeMappingInfo(
            [NotNull] MemberInfo member,
            [CanBeNull] string storeTypeName     = null,
            [CanBeNull] string storeTypeNameBase = null,
            bool?unicode  = null,
            int?size      = null,
            int?precision = null,
            int?scale     = null)
        {
            Check.NotNull(member, nameof(member));

            _coreTypeMappingInfo = new TypeMappingInfo(member, unicode, size, precision, scale);

            StoreTypeName     = storeTypeName;
            StoreTypeNameBase = storeTypeNameBase;
            IsFixedLength     = null;
        }
        /// <summary>
        ///     Creates a new instance of <see cref="TypeMappingInfo" />.
        /// </summary>
        /// <param name="type"> The CLR type in the model for which mapping is needed. </param>
        /// <param name="storeTypeName"> The database type name. </param>
        /// <param name="keyOrIndex"> If <c>true</c>, then a special mapping for a key or index may be returned. </param>
        /// <param name="unicode"> Specifies Unicode or ANSI mapping, or <c>null</c> for default. </param>
        /// <param name="size"> Specifies a size for the mapping, or <c>null</c> for default. </param>
        /// <param name="rowVersion"> Specifies a row-version, or <c>null</c> for default. </param>
        /// <param name="fixedLength"> Specifies a fixed length mapping, or <c>null</c> for default. </param>
        /// <param name="precision"> Specifies a precision for the mapping, or <c>null</c> for default. </param>
        /// <param name="scale"> Specifies a scale for the mapping, or <c>null</c> for default. </param>
        public RelationalTypeMappingInfo(
            [NotNull] Type type,
            [CanBeNull] string storeTypeName,
            bool keyOrIndex,
            bool?unicode,
            int?size,
            bool?rowVersion,
            bool?fixedLength,
            int?precision,
            int?scale)
        {
            _coreTypeMappingInfo = new TypeMappingInfo(type, keyOrIndex, unicode, size, rowVersion, precision, scale);

            IsFixedLength     = fixedLength;
            StoreTypeName     = storeTypeName;
            StoreTypeNameBase = ParseStoreTypeName(storeTypeName, out _parsedSize, out _parsedPrecision, out _parsedScale, out _isMax);
        }
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" /> with the given <see cref="ValueConverterInfo" />.
        /// </summary>
        /// <param name="source"> The source info. </param>
        /// <param name="converter"> The converter to apply. </param>
        public RelationalTypeMappingInfo(
            RelationalTypeMappingInfo source,
            ValueConverterInfo converter)
        {
            _coreTypeMappingInfo = new TypeMappingInfo(
                source._coreTypeMappingInfo,
                converter,
                source.IsUnicode,
                source.Size,
                source.Precision,
                source.Scale);

            var mappingHints = converter.MappingHints;

            StoreTypeName     = source.StoreTypeName;
            StoreTypeNameBase = ParseStoreTypeName(source.StoreTypeName, out _parsedSize, out _parsedPrecision, out _parsedScale, out _isMax);
            IsFixedLength     = source.IsFixedLength ?? (mappingHints as RelationalConverterMappingHints)?.IsFixedLength;
        }
Beispiel #17
0
        /// <summary>
        ///     Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
        /// </summary>
        /// <param name="property"> The property for which mapping is needed. </param>
        public RelationalTypeMappingInfo([NotNull] IProperty property)
        {
            _coreTypeMappingInfo = new TypeMappingInfo(property);

            var principals = property.FindPrincipals().ToList();

            var storeTypeName = principals
                                .Select(p => (string)p[RelationalAnnotationNames.ColumnType])
                                .FirstOrDefault(t => t != null);

            var fixedLength = principals
                              .Select(p => p.Relational().IsFixedLength)
                              .FirstOrDefault(t => t);

            IsFixedLength     = fixedLength;
            StoreTypeName     = storeTypeName;
            StoreTypeNameBase = ParseStoreTypeName(storeTypeName, out _parsedSize, out _parsedPrecision, out _parsedScale, out _isMax);
        }
        /// <summary>
        ///     Creates a new instance of <see cref="TypeMappingInfo" /> with the given <see cref="ValueConverterInfo" />.
        /// </summary>
        /// <param name="source"> The source info. </param>
        /// <param name="converter"> The converter to apply. </param>
        protected TypeMappingInfo(
            [NotNull] TypeMappingInfo source,
            ValueConverterInfo converter)
        {
            Check.NotNull(source, nameof(source));

            Property     = source.Property;
            IsRowVersion = source.IsRowVersion;
            IsKeyOrIndex = source.IsKeyOrIndex;
            MemberInfo   = source.MemberInfo;

            var mappingHints = converter.MappingHints;

            Size      = source.Size ?? mappingHints?.Size;
            IsUnicode = source.IsUnicode ?? mappingHints?.IsUnicode;
            Scale     = source.Scale ?? mappingHints?.Scale;
            Precision = source.Precision ?? mappingHints?.Precision;

            ClrType = converter.ProviderClrType.UnwrapNullableType();
        }
        /// <summary>
        ///     Creates a new instance of <see cref="TypeMappingInfo" /> with the given <see cref="ValueConverterInfo" />.
        /// </summary>
        /// <param name="source"> The source info. </param>
        /// <param name="builtInConverter"> The converter to apply. </param>
        protected TypeMappingInfo(
            [NotNull] TypeMappingInfo source,
            ValueConverterInfo builtInConverter)
        {
            Check.NotNull(source, nameof(source));

            Property     = source.Property;
            ModelClrType = source.ModelClrType;
            ConfiguredProviderClrType = source.ConfiguredProviderClrType;
            IsRowVersion = source.IsRowVersion;
            IsKeyOrIndex = source.IsKeyOrIndex;

            if (source._customConverter != null)
            {
                _customConverter = source._customConverter;

                ValueConverterInfo = new ValueConverterInfo(
                    _customConverter.ModelClrType,
                    builtInConverter.ProviderClrType,
                    i => _customConverter.ComposeWith(builtInConverter.Create()),
                    builtInConverter.MappingHints == null
                        ? _customConverter.MappingHints
                        : builtInConverter.MappingHints.With(_customConverter.MappingHints));
            }
            else
            {
                ValueConverterInfo = builtInConverter;
            }

            // ReSharper disable once VirtualMemberCallInConstructor
            var mappingHints = ValueConverterInfo?.MappingHints;

            Size            = source.Size ?? mappingHints?.Size;
            IsUnicode       = source.IsUnicode ?? mappingHints?.IsUnicode;
            Scale           = source.Scale ?? mappingHints?.Scale;
            Precision       = source.Precision ?? mappingHints?.Precision;
            ProviderClrType = CreateProviderClrType();
        }
Beispiel #20
0
            /// <summary>
            ///     Creates a new instance of <see cref="TypeMappingInfo" /> with the given <see cref="ValueConverterInfo" />.
            /// </summary>
            /// <param name="source"> The source info. </param>
            /// <param name="builtInConverter"> The converter to apply. </param>
            protected TypeMappingInfo(
                [NotNull] TypeMappingInfo source,
                ValueConverterInfo builtInConverter)
            {
                Check.NotNull(source, nameof(source));

                Property     = source.Property;
                ModelClrType = source.ModelClrType;
                StoreClrType = source.StoreClrType;
                IsRowVersion = source.IsRowVersion;
                IsKeyOrIndex = source.IsKeyOrIndex;

                if (source._customConverter != null)
                {
                    _customConverter = source._customConverter;

                    ValueConverterInfo = new ValueConverterInfo(
                        _customConverter.ModelType,
                        builtInConverter.StoreClrType,
                        i => _customConverter.ComposeWith(builtInConverter.Create()),
                        _customConverter.MappingHints.With(builtInConverter.MappingHints));
                }
                else
                {
                    ValueConverterInfo = builtInConverter;
                }

                // ReSharper disable once VirtualMemberCallInConstructor
                var mappingHints = ValueConverterInfo?.MappingHints ?? default;

                Size          = CalculateSize(mappingHints, source.Size ?? mappingHints.Size);
                IsUnicode     = source.IsUnicode ?? mappingHints.IsUnicode;
                IsFixedLength = source.IsFixedLength ?? mappingHints.IsFixedLength;
                Scale         = source.Scale ?? mappingHints.Scale;
                Precision     = source.Precision ?? mappingHints.Precision;
            }
Beispiel #21
0
        /// <summary>
        ///     Creates a new instance of <see cref="TypeMappingInfo" /> with the given <see cref="ValueConverterInfo" />.
        /// </summary>
        /// <param name="source"> The source info. </param>
        /// <param name="converter"> The converter to apply. </param>
        /// <param name="unicode"> Specifies Unicode or ANSI mapping, or <c>null</c> for default. </param>
        /// <param name="size"> Specifies a size for the mapping, or <c>null</c> for default. </param>
        /// <param name="precision"> Specifies a precision for the mapping, or <c>null</c> for default. </param>
        /// <param name="scale"> Specifies a scale for the mapping, or <c>null</c> for default. </param>
        public TypeMappingInfo(
            TypeMappingInfo source,
            ValueConverterInfo converter,
            bool?unicode  = null,
            int?size      = null,
            int?precision = null,
            int?scale     = null)
        {
            Check.NotNull(source, nameof(source));

            IsRowVersion     = source.IsRowVersion;
            IsKeyOrIndex     = source.IsKeyOrIndex;
            _providerClrType = source._providerClrType;
            _customConverter = source._customConverter;

            var mappingHints = converter.MappingHints;

            Size      = size ?? source.Size ?? mappingHints?.Size;
            IsUnicode = unicode ?? source.IsUnicode ?? mappingHints?.IsUnicode;
            Scale     = scale ?? source.Scale ?? mappingHints?.Scale;
            Precision = precision ?? source.Precision ?? mappingHints?.Precision;

            ClrType = converter.ProviderClrType.UnwrapNullableType();
        }
 /// <summary>
 ///     <para>
 ///         Overridden by 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 CoreTypeMapping FindMapping(TypeMappingInfo mappingInfo);
Beispiel #23
0
        private CoreTypeMapping FindMappingWithConversion(
            TypeMappingInfo mappingInfo,
            [CanBeNull] IProperty property)
        {
            Check.NotNull(mappingInfo, nameof(mappingInfo));

            var principals = property?.FindPrincipals().ToList();

            var customConverter = principals
                                  ?.Select(p => p.GetValueConverter())
                                  .FirstOrDefault(c => c != null);

            var providerClrType = principals
                                  ?.Select(p => p.GetProviderClrType())
                                  .FirstOrDefault(t => t != null)
                                  ?.UnwrapNullableType();

            var resolvedMapping = _explicitMappings.GetOrAdd(
                mappingInfo,
                k =>
            {
                var mapping = providerClrType == null ||
                              providerClrType == mappingInfo.ClrType
                        ? FindMapping(mappingInfo)
                        : null;

                if (mapping == null)
                {
                    var sourceType = mappingInfo.ClrType;

                    if (sourceType != null)
                    {
                        foreach (var converterInfo in Dependencies
                                 .ValueConverterSelector
                                 .Select(sourceType, providerClrType))
                        {
                            var mappingInfoUsed = mappingInfo.WithConverter(converterInfo);
                            mapping             = FindMapping(mappingInfoUsed);

                            if (mapping == null &&
                                providerClrType != null)
                            {
                                foreach (var secondConverterInfo in Dependencies
                                         .ValueConverterSelector
                                         .Select(providerClrType))
                                {
                                    mapping = FindMapping(mappingInfoUsed.WithConverter(secondConverterInfo));

                                    if (mapping != null)
                                    {
                                        mapping = mapping.Clone(secondConverterInfo.Create());
                                        break;
                                    }
                                }
                            }

                            if (mapping != null)
                            {
                                mapping = mapping.Clone(converterInfo.Create());
                                break;
                            }
                        }
                    }
                }

                if (mapping != null &&
                    customConverter != null)
                {
                    mapping = mapping.Clone(customConverter);
                }

                return(mapping);
            });

            ValidateMapping(resolvedMapping, property);

            return(resolvedMapping);
        }
        /// <summary>
        ///     <para>
        ///         Uses any available <see cref="ValueConverter" /> to help find a mapping that works.
        ///     </para>
        ///     <para>
        ///         Note: providers should typically not need to override this method.
        ///     </para>
        /// </summary>
        /// <param name="mappingInfo"> The mapping info. </param>
        /// <returns> The type mapping with conversions applied, or <c>null</c> if none could be found. </returns>
        protected virtual CoreTypeMapping FindMappingWithConversion([NotNull] TypeMappingInfo mappingInfo)
        {
            Check.NotNull(mappingInfo, nameof(mappingInfo));

            return(_explicitMappings.GetOrAdd(
                       mappingInfo,
                       k =>
            {
                var principals = mappingInfo.Property?.FindPrincipals().ToList();

                var customConverter = principals
                                      ?.Select(p => p.GetValueConverter())
                                      .FirstOrDefault(c => c != null);

                if (customConverter != null)
                {
                    mappingInfo = mappingInfo.WithConverter(
                        new ValueConverterInfo(
                            customConverter.ModelClrType,
                            customConverter.ProviderClrType,
                            i => customConverter,
                            customConverter.MappingHints));
                }

                var providerClrType = principals
                                      ?.Select(p => p.GetProviderClrType())
                                      .FirstOrDefault(t => t != null)
                                      ?.UnwrapNullableType();

                var mapping = providerClrType == null ||
                              providerClrType == mappingInfo.ClrType
                        ? FindMapping(mappingInfo)
                        : null;

                if (mapping == null)
                {
                    var sourceType = mappingInfo.ClrType;

                    if (sourceType != null)
                    {
                        foreach (var converterInfo in Dependencies
                                 .ValueConverterSelector
                                 .Select(sourceType, providerClrType))
                        {
                            var mappingInfoUsed = mappingInfo.WithConverter(converterInfo);
                            mapping = FindMapping(mappingInfoUsed);

                            if (mapping == null &&
                                providerClrType != null)
                            {
                                foreach (var secondConverterInfo in Dependencies
                                         .ValueConverterSelector
                                         .Select(providerClrType))
                                {
                                    mapping = FindMapping(mappingInfoUsed.WithConverter(secondConverterInfo));

                                    if (mapping != null)
                                    {
                                        mapping = mapping.Clone(secondConverterInfo.Create());
                                        break;
                                    }
                                }
                            }

                            if (mapping != null)
                            {
                                mapping = mapping.Clone(converterInfo.Create());
                                break;
                            }
                        }
                    }
                }

                if (mapping != null &&
                    customConverter != null)
                {
                    mapping = mapping.Clone(customConverter);
                }

                return mapping;
            }));
        }
 /// <summary>
 ///     Overridden to call <see cref="FindMapping(RelationalTypeMappingInfo)" />
 /// </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 override CoreTypeMapping FindMapping(TypeMappingInfo mappingInfo)
 => throw new InvalidOperationException("FindMapping on a 'RelationalTypeMappingSource' with a non-relational 'TypeMappingInfo'.");
Beispiel #26
0
        /// <summary>
        ///     <para>
        ///         Uses any available <see cref="ValueConverter" /> to help find a mapping that works.
        ///     </para>
        ///     <para>
        ///         Note: providers should typically not need to override this method.
        ///     </para>
        /// </summary>
        /// <param name="mappingInfo"> The mapping info. </param>
        /// <returns> The type mapping with conversions applied, or <c>null</c> if none could be found. </returns>
        protected virtual CoreTypeMapping FindMappingWithConversion([NotNull] TypeMappingInfo mappingInfo)
        {
            Check.NotNull(mappingInfo, nameof(mappingInfo));

            return(_explicitMappings.GetOrAdd(
                       mappingInfo,
                       k =>
            {
                var mappingInfoUsed = mappingInfo;

                var mapping = mappingInfoUsed.ConfiguredProviderClrType == null ||
                              mappingInfoUsed.ConfiguredProviderClrType == mappingInfoUsed.ModelClrType
                        ? FindMapping(mappingInfoUsed)
                        : null;

                if (mapping == null)
                {
                    var sourceType = mappingInfo.ValueConverterInfo?.ProviderClrType ?? mappingInfo.ModelClrType;

                    if (sourceType != null)
                    {
                        foreach (var converterInfo in Dependencies
                                 .ValueConverterSelector
                                 .Select(sourceType, mappingInfo.ConfiguredProviderClrType))
                        {
                            mappingInfoUsed = mappingInfo.WithBuiltInConverter(converterInfo);
                            mapping = FindMapping(mappingInfoUsed);

                            if (mapping == null &&
                                mappingInfo.ConfiguredProviderClrType != null)
                            {
                                foreach (var secondConverterInfo in Dependencies
                                         .ValueConverterSelector
                                         .Select(mappingInfo.ConfiguredProviderClrType))
                                {
                                    var secondMappingInfoUsed = mappingInfoUsed.WithBuiltInConverter(secondConverterInfo);
                                    mapping = FindMapping(secondMappingInfoUsed);

                                    if (mapping != null)
                                    {
                                        mapping = mapping.Clone(secondMappingInfoUsed.ValueConverterInfo?.Create());
                                        break;
                                    }
                                }
                            }

                            if (mapping != null)
                            {
                                break;
                            }
                        }
                    }
                }

                if (mapping != null &&
                    mappingInfoUsed.ValueConverterInfo != null)
                {
                    mapping = mapping.Clone(mappingInfoUsed.ValueConverterInfo?.Create());
                }

                return mapping;
            }));
        }
Beispiel #27
0
 /// <summary>
 ///     <para>
 ///         Overridden by 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 CoreTypeMapping FindMapping([NotNull] TypeMappingInfo mappingInfo);
Beispiel #28
0
 /// <summary>
 ///     Overridden to call <see cref="FindMapping(RelationalTypeMappingInfo)" />
 /// </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 override CoreTypeMapping FindMapping(TypeMappingInfo mappingInfo)
 => FindMapping((RelationalTypeMappingInfo)mappingInfo);