System.Data.SQLite如何处理.NET数据类型?

8
我很难找到关于System.Data.SQLite在不同的.NET数据类型方面的行为的文档。
比如说,System.Data.SQLite如何在SQLite数据库中存储.NET布尔值?有几种可能的方法:
- 整数0和1 - 整数0和-1 - 文本“True”和“False” - 文本“T”和“F” - 文本“Y”和“N” - 等等……
反过来,SQLite如何解析布尔值?System.Data.SQLite期望特定的格式吗?是什么格式?
这方面缺乏文档让人沮丧。也许我没有找对地方?
注意:这不是一个关于布尔值的问题。我正在寻找解释所有.NET数据类型行为的文档。
1个回答

10
我建议您先阅读与驱动程序无关的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() 方法。


哇,现在我们可以开始谈了。谢谢你。我刚刚开始做一些测试(将键入的参数插入到没有亲和力的列中),以反向工程行为。你刚刚节省了我宝贵的时间 :-) - misha256
相关的是,我刚刚发现在CREATE TABLE SQL中指定的数据类型对System.Data.SQLite有意义。一个被定义为INT16的列对SQLite本身有一些意义(你会得到INTEGER亲和性),但是System.Data.SQLite将注意到INT16的定义并解析为Int16(如果可以的话)。所有这些都是非常有价值的信息。我很想在某个地方写下这篇博客... - misha256
@misha256:对下一个人来说可能是个好主意 :-) 我承认阅读源代码不像阅读写得好的文档那么愉快! - Cameron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接