我建议您先阅读与驱动程序无关的
SQLite文档。该文档解释了布尔值应如何存储以及不同的日期时间序列化方案等内容。
更多细节可在System.Data.SQLite中找到,它是开源的,并且虽然在某些方面有点复杂,但通常很容易阅读。
例如,在
SQLiteDataReader.cs中实现的ADO.NET
IDataReader
接口的
GetValue()
方法会调用一个名为
GetSQLiteType()
的方法,然后根据一些连接标志进行更多的自动检测。
GetSQLiteType()
和相关方法都指向
SQLiteConvert类,该类执行实际的类型转换和检测。这些转换都在那里定义(在许多日期操作助手之后的中间开始)。最终,您将到达这个与您的问题特别相关的函数:
internal static TypeAffinity TypeToAffinity(Type typ)
{
TypeCode tc = Type.GetTypeCode(typ);
if (tc == TypeCode.Object)
{
if (typ == typeof(byte[]) || typ == typeof(Guid))
return TypeAffinity.Blob;
else
return TypeAffinity.Text;
}
return _typecodeAffinities[(int)tc];
}
private static TypeAffinity[] _typecodeAffinities = {
TypeAffinity.Null, // Empty (0)
TypeAffinity.Blob, // Object (1)
TypeAffinity.Null, // DBNull (2)
TypeAffinity.Int64, // Boolean (3)
TypeAffinity.Int64, // Char (4)
TypeAffinity.Int64, // SByte (5)
TypeAffinity.Int64, // Byte (6)
TypeAffinity.Int64, // Int16 (7)
TypeAffinity.Int64, // UInt16 (8)
TypeAffinity.Int64, // Int32 (9)
TypeAffinity.Int64, // UInt32 (10)
TypeAffinity.Int64, // Int64 (11)
TypeAffinity.Int64, // UInt64 (12)
TypeAffinity.Double, // Single (13)
TypeAffinity.Double, // Double (14)
TypeAffinity.Double, // Decimal (15)
TypeAffinity.DateTime, // DateTime (16)
TypeAffinity.Null, // ?? (17)
TypeAffinity.Text // String (18)
};
一般来说,整数类型会被正确映射到SQLite的(64位)整数,并且字符串也是如此。 byte[]
数组和 Guid
也可以透明地工作,但都存储为 blob。布尔值映射为1(true)和0(false)整数。所有 SQLite 的日期时间表示形式都受支持,还有更多:请参见Bind_DateTime()
方法。
CREATE TABLE
SQL中指定的数据类型对System.Data.SQLite有意义。一个被定义为INT16的列对SQLite本身有一些意义(你会得到INTEGER亲和性),但是System.Data.SQLite将注意到INT16的定义并解析为Int16
(如果可以的话)。所有这些都是非常有价值的信息。我很想在某个地方写下这篇博客... - misha256