Предлагаю вам начать работу с водителем-агностиком SQLite documentation on the subject. В нем объясняется, как должны храниться булевы, и, например, различные схемы сериализации datetime.
Для получения более подробной информации System.Data.SQLite является открытым исходным кодом и в то же время немного крутым вокруг определенных краев, как правило, довольно легко читается.
Например, GetValue()
метод (часть интерфейса ADO.NET IDataReader
, который реализован) в SQLiteDataReader.cs вызывает метод с именем 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)
};
В общем, целочисленные типы будут получать правильно сопоставлен (64-разрядных) целых SQLite и обратно, и повторы строк. byte[]
и Guid
s будут работать прозрачно, хотя оба сохраняются как капли. Булевские значения отображаются в 1 (true) и 0 (false) целые числа. И все представления SQLite datetime поддерживаются, и многое другое: см. Метод Bind_DateTime()
в SQLite3.cs.
Вау, теперь мы говорим. Спасибо.Я только начал делать некоторые тесты (вставляя типизированные параметры в столбцы без привязки), чтобы перестроить поведение. Вы только что сэкономили мне драгоценное время :-) – misha256
В связанной заметке я только что обнаружил, что типы данных, указанные в 'CREATE TABLE' SQL *, имеют значение для System.Data.SQLite *. Столбец, определенный как INT16, имеет какое-то значение для самого SQLite (вы получаете INTEGER Affinity) *, но * System.Data.SQLite заметит определение INT16 и проанализирует 'Int16', если это возможно. Все это ценная информация. У меня возникает соблазн, чтобы блог это где-то ... – misha256
@ misha256: Может быть хорошей идеей для следующего человека :-) Я признаю, что чтение источника не так приятно, как хорошо написанная документация будет! – Cameron