public NpgsqlEFTypeMapper([NotNull] RelationalTypeMapperDependencies dependencies)
            : base(dependencies)
        {
            // First, PostgreSQL type name (string) -> RelationalTypeMapping
            _storeTypeMappings = TypeHandlerRegistry.HandlerTypes.Values
                                 .Where(tam => tam.Mapping.NpgsqlDbType.HasValue)
                                 .Select(tam => new {
                Name    = tam.Mapping.PgName,
                Mapping = (RelationalTypeMapping) new NpgsqlBaseTypeMapping(tam.Mapping.PgName, GetTypeHandlerTypeArgument(tam.HandlerType), tam.Mapping.NpgsqlDbType.Value)
            })
                                 .ToDictionary(x => x.Name, x => x.Mapping);

            // Second, CLR type -> RelationalTypeMapping
            _baseClrMappings = TypeHandlerRegistry.HandlerTypes.Values
                               .Select(tam => tam.Mapping)
                               .Where(m => m.NpgsqlDbType.HasValue)
                               .SelectMany(m => m.ClrTypes, (m, t) => new {
                Type    = t,
                Mapping = (RelationalTypeMapping) new NpgsqlBaseTypeMapping(m.PgName, t, m.NpgsqlDbType.Value)
            })
                               .ToDictionary(x => x.Type, x => x.Mapping);

            _extraClrMappings = new ConcurrentDictionary <Type, RelationalTypeMapping>();

            StringMapper = new NpgsqlStringRelationalTypeMapper();

            AddCustomizedMappings();
            AddArrayStoreMappings();
        }
        public NpgsqlTypeMapper()
        {
            // First, PostgreSQL type name (string) -> RelationalTypeMapping
            _storeTypeMappings = TypeHandlerRegistry.HandlerTypes.Values
                                 // Base types
                                 .Where(tam => tam.Mapping.NpgsqlDbType.HasValue)
                                 .Select(tam => new {
                Name    = tam.Mapping.PgName,
                Mapping = (RelationalTypeMapping) new NpgsqlBaseTypeMapping(tam.Mapping.PgName, GetTypeHandlerTypeArgument(tam.HandlerType), tam.Mapping.NpgsqlDbType.Value)
            })
                                 // Enums
                                 //.Concat(TypeHandlerRegistry.GlobalEnumMappings.Select(kv => new {
                                 //    Name = kv.Key,
                                 //    Mapping = (RelationalTypeMapping)new NpgsqlTypeMapping(kv.Key, ((IEnumHandler)kv.Value).EnumType)
                                 //}))
                                 // Composites
                                 //.Concat(TypeHandlerRegistry.GlobalCompositeMappings.Select(kv => new {
                                 //    Name = kv.Key,
                                 //    Mapping = (RelationalTypeMapping)new NpgsqlTypeMapping(kv.Key, ((ICompositeHandler)kv.Value).CompositeType)
                                 //}))
                                 // Output
                                 .ToDictionary(x => x.Name, x => x.Mapping);

            // Second, CLR type -> RelationalTypeMapping
            _clrTypeMappings = TypeHandlerRegistry.HandlerTypes.Values
                               // Base types
                               .Select(tam => tam.Mapping)
                               .Where(m => m.NpgsqlDbType.HasValue)
                               .SelectMany(m => m.ClrTypes, (m, t) => new {
                Type    = t,
                Mapping = (RelationalTypeMapping) new NpgsqlBaseTypeMapping(m.PgName, t, m.NpgsqlDbType.Value)
            })
                               // Enums
                               //.Concat(TypeHandlerRegistry.GlobalEnumMappings.Select(kv => new {
                               //    Type = ((IEnumHandler)kv.Value).EnumType,
                               //    Mapping = (RelationalTypeMapping)new NpgsqlTypeMapping(kv.Key, ((IEnumHandler)kv.Value).EnumType)
                               //}))
                               // Composites
                               //.Concat(TypeHandlerRegistry.GlobalCompositeMappings.Select(kv => new {
                               //    Type = ((ICompositeHandler)kv.Value).CompositeType,
                               //    Mapping = (RelationalTypeMapping)new NpgsqlTypeMapping(kv.Key, ((ICompositeHandler)kv.Value).CompositeType)
                               //}))
                               // Output
                               .ToDictionary(x => x.Type, x => x.Mapping);

            // uint is special: there are three internal system uint types: oid, xid, cid. None are supposed to
            // be truly user-facing, so we don't want to automatically map uint properties to any of them.
            // However, if the user explicitly sets the properties store type to oid/xid/cid, we want to allow
            // that (especially since the xmin system column is important for optimistic concurrency).
            // EFCore doesn't allow a situation where a CLR type has no default store type, so we arbitrarily
            // choose oid.
            _clrTypeMappings[typeof(uint)] = new NpgsqlBaseTypeMapping("oid", typeof(uint), NpgsqlDbType.Oid);

            StringMapper = new NpgsqlStringRelationalTypeMapper();
        }
        public NpgsqlTypeMapper()
        {
            // First, PostgreSQL type name (string) -> RelationalTypeMapping
            _storeTypeMappings = TypeHandlerRegistry.HandlerTypes.Values
                                 // Base types
                                 .Where(tam => tam.Mapping.NpgsqlDbType.HasValue)
                                 .Select(tam => new {
                Name    = tam.Mapping.PgName,
                Mapping = (RelationalTypeMapping) new NpgsqlTypeMapping(tam.Mapping.PgName, GetTypeHandlerTypeArgument(tam.HandlerType), tam.Mapping.NpgsqlDbType.Value)
            })
                                 // Enums
                                 //.Concat(TypeHandlerRegistry.GlobalEnumMappings.Select(kv => new {
                                 //    Name = kv.Key,
                                 //    Mapping = (RelationalTypeMapping)new NpgsqlTypeMapping(kv.Key, ((IEnumHandler)kv.Value).EnumType)
                                 //}))
                                 // Composites
                                 //.Concat(TypeHandlerRegistry.GlobalCompositeMappings.Select(kv => new {
                                 //    Name = kv.Key,
                                 //    Mapping = (RelationalTypeMapping)new NpgsqlTypeMapping(kv.Key, ((ICompositeHandler)kv.Value).CompositeType)
                                 //}))
                                 // Output
                                 .ToDictionary(x => x.Name, x => x.Mapping);

            // Second, CLR type -> RelationalTypeMapping
            _clrTypeMappings = TypeHandlerRegistry.HandlerTypes.Values
                               // Base types
                               .Select(tam => tam.Mapping)
                               .Where(m => m.NpgsqlDbType.HasValue)
                               .SelectMany(m => m.ClrTypes, (m, t) => new {
                Type    = t,
                Mapping = (RelationalTypeMapping) new NpgsqlTypeMapping(m.PgName, t, m.NpgsqlDbType.Value)
            })
                               // Enums
                               //.Concat(TypeHandlerRegistry.GlobalEnumMappings.Select(kv => new {
                               //    Type = ((IEnumHandler)kv.Value).EnumType,
                               //    Mapping = (RelationalTypeMapping)new NpgsqlTypeMapping(kv.Key, ((IEnumHandler)kv.Value).EnumType)
                               //}))
                               // Composites
                               //.Concat(TypeHandlerRegistry.GlobalCompositeMappings.Select(kv => new {
                               //    Type = ((ICompositeHandler)kv.Value).CompositeType,
                               //    Mapping = (RelationalTypeMapping)new NpgsqlTypeMapping(kv.Key, ((ICompositeHandler)kv.Value).CompositeType)
                               //}))
                               // Output
                               .ToDictionary(x => x.Type, x => x.Mapping);

            StringMapper = new NpgsqlStringRelationalTypeMapper();
        }