Skip to main content

Type Mapping

nicyeAbout 3 minAbout 844 words

Type Mapping

Type Mapping (Default)

Note: Due to formatting issues, not all supported databases are displayed.

CSharpMySqlSqlServerPostgreSQLOracleSqliteDameng
bool | bool?bit(1)bitboolnumber(1)booleannumber(1)
sbyte | sbyte?tinyint(3)smallintint2number(4)smallintnumber(4)
short | short?smallint(6)smallintint2number(6)smallintnumber(6)
int | int?int(11)intint4number(11)integernumber(11)
long | long?bigint(20)bigintint8number(21)integernumber(21)
byte | byte?tinyint(3) unsignedtinyintint2number(3)int2number(3)
ushort | ushort?smallint(5) unsignedintint4number(5)unsignednumber(5)
uint | uint?int(10) unsignedbigintint8number(10)decimal(10,0)number(10)
ulong | ulong?bigint(20) unsigneddecimal(20,0)numeric(20,0)number(20)decimal(21,0)number(20)
double | double?doublefloatfloat8float(126)doubledouble
float | float?floatrealfloat4float(63)floatreal
decimal | decimal?decimal(10,2)decimal(10,2)numeric(10,2)number(10,2)decimal(10,2)number(10,2)
Guid | Guid?char(36)uniqueidentifieruuidchar(36 CHAR)character(36)char(36)
TimeSpan | TimeSpan?timetimetimeinterval day(2) to second(6)bigint-
DateTime | DateTime?datetimedatetimetimestamptimestamp(6)datetimetimestamp(6)
DateTimeOffset | DateTimeOffset?-datetimeoffset-timestamp(6) with local time zone-timestamp(6)
Enum | Enum?enumintint4number(16)mediumintnumber(16)
FlagsEnum | FlagsEnum?setbigintint8number(32)bigintnumber(32)
byte[]varbinary(255)varbinary(255)byteablobblobblob
stringvarchar(255)nvarchar(255)varchar(255)nvarchar2(255)nvarchar(255)nvarchar2(255)

For string specifying length [Column(DbType = "varchar(max)")] or [MaxLength(-1)] or [Column(StringLength = -1)], when length is -1, the mapping is as follows:

MySqlPostgreSQLSqlServerOracleSqliteFirebirdDuckDBMsAccessDamengKingbase
texttextvarchar(max)nclobtextblob sub_type 1textlongtexttexttext

Note: MySql [MaxLength(-2)] or [Column(StringLength = -2)] maps to longtext

For decimal specifying length [Column(Precision = 10, Scale = 2)]

MapType

Using MapType Enum -> string/int etc.:

class Table
{
    [Column(MapType = typeof(string))]
    public PeopleType t1 { get; set; }

    [Column(MapType = typeof(int))]
    public PeopleType t2 { get; set; }

    [Column(MapType = typeof(string))]
    public BigInteger t3 { get; set; }
}
public enum PeopleType { TaiWan, abc, HongKong }

Json

dotnet add package FreeSql.Extensions.JsonMap

fsql.UseJsonMap(); //Open

class Table
{
    public int Id { get; set; }

    [JsonMap]
    public TableOptions Options { get; set; }
}
class TableOptions
{
    public int Value1 { get; set; }
    public string Value2 { get; set; }
}

fsql.Select<Table>().Where(a => a.Options.Value1 == 100 && a.Options.Value2 == "xx").ToList();
//WHERE json_extract(a."Options",'$.Value1') = 100 AND json_extract(a."Options",'$.Value2') = 'xx'

TypeHandlers (Custom)

FreeSql.Internal.Utils.TypeHandlers.TryAdd(typeof(JsonPoco), new JsonPocoTypeHandler());
FreeSql.Internal.Utils.TypeHandlers.TryAdd(typeof(DateOnly), new DateOnlyTypeHandler());
FreeSql.Internal.Utils.TypeHandlers.TryAdd(typeof(DateTimeOffset), new DateTimeOffsetTypeHandler());

class Product
{
    public JsonPoco json { get; set; }
    public DateOnly date { get; set; }
    public DateTimeOffset dateTimeOffset { get; set; }
}
class JsonPoco
{
    public int a { get; set; }
    public int b { get; set; }
}
class JsonPocoTypeHandler : TypeHandler<JsonPoco>
{
    public override object Serialize(JsonPoco value) => JsonConvert.SerializeObject(value);
    public override JsonPoco Deserialize(object value) => JsonConvert.DeserializeObject<JsonPoco>((string)value);
    public override void FluentApi(FluentColumn col) => col.MapType(typeof(string)).StringLength(-1);
}
class DateOnlyTypeHandler : TypeHandler<DateOnly>
{
    public override object Serialize(DateOnly value) => value.ToString("yyyy-MM-dd");
    public override DateOnly Deserialize(object value) => DateOnly.TryParse(string.Concat(value), out var trydo) ? trydo : DateOnly.MinValue;
    public override void FluentApi(FluentColumn col) => col.MapType(typeof(string)).StringLength(12);
}
class DateTimeOffsetTypeHandler : TypeHandler<DateTimeOffset>
{
    public override object Serialize(DateTimeOffset value) => value.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss");
    public override DateTimeOffset Deserialize(object value) => DateTimeOffset.TryParse((string)value, out var dts) ? dts : DateTimeOffset.MinValue;
    public override void FluentApi(FluentColumn col) => col.MapType(typeof(string)).DbType("datetime");
}

Type Mapping (Special)

FreeSql.Provider.MySql/MySqlConnector:

CSharpMySql
MygisPointpoint
MygisLineStringlinestring
MygisPolygonpolygon
MygisMultiPointmultipoint
MygisMultiLineStringmultilinestring
MygisMultiPolygonmultipolygon

If int, byte types specify DbType="tinyint(1)", please note that tinyint(1) is by default mapped to bool in ado.net. You can specify TreatTinyAsBoolean=false in the connection string to map tinyint(1) to SByte instead of bool.

FreeSql.Provider.PostgreSQL:

CSharpPostgreSQL
BitArrayvarbit(64)
NpgsqlPoint | NpgsqlPoint?point
NpgsqlLine | NpgsqlLine?line
NpgsqlLSeg | NpgsqlLSeg?lseg
NpgsqlBox | NpgsqlBox?box
NpgsqlPath | NpgsqlPath?path
NpgsqlPolygon | NpgsqlPolygon?polygon
NpgsqlCircle | NpgsqlCircle?circle
(IPAddress Address, int Subnet) | (IPAddress Address, int Subnet)?
csharpPostgreSQL
BitArrayvarbit(64)
NpgsqlPoint | NpgsqlPoint?point
NpgsqlLine | NpgsqlLine?line
NpgsqlLSeg | NpgsqlLSeg?lseg
NpgsqlBox | NpgsqlBox?box
NpgsqlPath | NpgsqlPath?path
NpgsqlPolygon | NpgsqlPolygon?polygon
NpgsqlCircle | NpgsqlCircle?circle
(IPAddress Address, int Subnet) | (IPAddress Address, int Subnet)?cidr
IPAddressinet
PhysicalAddressmacaddr
NpgsqlRange<int> | NpgsqlRange<int>?int4range
NpgsqlRange<long> | NpgsqlRange<long>?int8range
NpgsqlRange<decimal> | NpgsqlRange<decimal>?numrange
NpgsqlRange<DateTime> | NpgsqlRange<DateTime>?tsrange
PostgisPointgeometry
PostgisLineStringgeometry
PostgisPolygongeometry
PostgisMultiPointgeometry
PostgisMultiLineStringgeometry
PostgisMultiPolygongeometry
PostgisGeometrygeometry
PostgisGeometryCollectiongeometry
Dictionary<string, string>hstore
JTokenjsonb
JObjectjsonb
JArrayjsonb
ArrayAll the above types are supported, including default types

Rewrite/Re-read

Rewrite SQL on write and rewrite SQL on read, suitable for read/write scenarios with geography types.

[Column(DbType = "geography", 
    RewriteSql = "geography::STGeomFromText({0}, 4236)", 
    RereadSql = "{0}.STAsText()")]
public string geo { get; set; }

// Insert: INSERT INTO [ts_geocrud01]([id], [geo]) VALUES(@id_0, geography::STGeomFromText(@geo_0, 4236))

// Query: SELECT TOP 1 a.[id], a.[geo].STAsText() 
// FROM [ts_geocrud01] a 
// WHERE (a.[id] = 'c7227d5e-0bcf-4b71-8f0f-d69a552fe84e')