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();
        }
Exemplo n.º 2
0
        void AddCustomizedMappings()
        {
            // Mappings where we need literal string generation
            _baseClrMappings[typeof(string)] = _storeTypeMappings["text"] = new NpgsqlStringTypeMapping("text", NpgsqlDbType.Text);
            _storeTypeMappings["varchar"]    = new NpgsqlStringTypeMapping("varchar", NpgsqlDbType.Varchar);
            _storeTypeMappings["char"]       = new NpgsqlStringTypeMapping("char", NpgsqlDbType.Char);
            _storeTypeMappings["citext"]     = new NpgsqlStringTypeMapping("citext", NpgsqlDbType.Citext);
            _storeTypeMappings["json"]       = new NpgsqlStringTypeMapping("json", NpgsqlDbType.Json);
            _storeTypeMappings["jsonb"]      = new NpgsqlStringTypeMapping("jsonb", NpgsqlDbType.Jsonb);

            _baseClrMappings[typeof(char)]           = new CharTypeMapping("text", DbType.String);
            _baseClrMappings[typeof(DateTime)]       = _storeTypeMappings["timestamp"] = new DateTimeTypeMapping("timestamp", DbType.DateTime);
            _baseClrMappings[typeof(DateTimeOffset)] = _storeTypeMappings["timestamptz"] = new NpgsqlDateTimeOffsetTypeMapping("timestamptz", DbType.DateTimeOffset);
            _baseClrMappings[typeof(TimeSpan)]       = _storeTypeMappings["interval"] = new NpgsqlTimeSpanTypeMapping();
            _baseClrMappings[typeof(bool)]           = _storeTypeMappings["bool"] = new NpgsqlBoolTypeMapping();

            _baseClrMappings[typeof(decimal)] = new DecimalTypeMapping("numeric", DbType.Decimal);
            // Note that "decimal" in PostgreSQL is just an alias for numeric, PostgreSQL itself always reports numeric for column types.

            _baseClrMappings[typeof(Guid)]   = _storeTypeMappings["uuid"] = new GuidTypeMapping("uuid", DbType.Guid);
            _baseClrMappings[typeof(byte[])] = _storeTypeMappings["bytea"] = new NpgsqlByteArrayTypeMapping();

            // The following isn't necessary for int itself - a simple ToString() (the default) produces the right
            // literal representation. However, with an explicit int mapping the standard mapping would be returned
            // for enums, and there a simple ToString produces the enum *name*.
            // Example for test for enum literal: InheritanceNpgsqlTest.Can_query_just_roses
            _baseClrMappings[typeof(short)] = _storeTypeMappings["int2"] = new ShortTypeMapping("int2", DbType.Int16);
            _baseClrMappings[typeof(int)]   = _storeTypeMappings["int4"] = new IntTypeMapping("int4", DbType.Int32);
            _baseClrMappings[typeof(long)]  = _storeTypeMappings["int8"] = new LongTypeMapping("int8", DbType.Int64);

            // 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.
            _baseClrMappings[typeof(uint)] = new NpgsqlBaseTypeMapping("oid", typeof(uint), NpgsqlDbType.Oid);
        }