Sqlite с помощью Dapper. Ошибка разбора столбца. Невозможно привести объект типа System.Int64 к типу System.Double

Я использую fastcrud и dapper для сопоставления результатов моего запроса с моим пользовательским типом. Я исследовал библиотеку dapper и пришел к выводу, что это проблема пакета Microsoft.Data.Sqlite. Не уверен, что это нужно исправить там, но это проблема.

Перед анализом каждой строки в результате запроса Dapper использует метод GetFieldType из класса SqliteDataReader для получения правильных типов столбцов.

Представьте себе следующую таблицу:

Id | MinTemp | MaxTemp

1  | 10.5    | 18.2 

2  | 10.6    | 20 

sqlitedatareader.GetFieldType Метод даст вам следующие типы:

System.Int64 для Id и System.Double для MinTemp и MaxTemp Это кажется правильным, но при синтаксическом анализе результатов в строке 2 возникает следующая ошибка

Ошибка анализа столбца 10 (MaxTemp=20 - Int64). Невозможно привести объект типа "System.Int64" к типу "System.Double".

Из-за динамической системы типов SQLite он изменяет тип MaxTemp в строке 2 на System.Int64. Но поскольку dapper определил тип MaxTemp для удвоения, это вызывает ошибку, упомянутую выше.

Если я изменю свое значение MaxTemp в моей базе данных sqlite на 20.00001, проблема будет исправлена, но это не правильно.

Используемые пакеты: "Microsoft.Data.Sqlite": "1.0.0"

Кто-нибудь знает, как решить эту проблему?

2 ответа

Это похоже на ошибку / недостаток в Dapper:

https://github.com/StackExchange/Dapper/issues/642

Поскольку SQLite использует сходство значений, значение 20 во второй строке примера рассматривается как INT. (Даже если он был буквально вставлен как '20.0' или же '20.00' так далее.)

Очевидно, Dapper не может индивидуально обрабатывать различные типы, которые возвращаются для каждого отдельного поля.

Обходным путем для этого является использование SQL CAST(). Пример:

SELECT CAST(field123 AS REAL) AS field123 FROM ...

Это кажется, чтобы обойти ошибку.

Другой обходной путь на случай, если вы не можете контролировать сам запрос, состоит в том, чтобы изменить тип свойства, с которым вы выполняете сопоставление, на «строку».

Например, если это не удается при попытке проанализировать столбец как целое число:

      Id | MyField 
------------
1  | "Hello" 

2  |   999  

Вы можете изменить свое свойство MyField, чтобы оно было строкой вместо int, а затем безопасно попытаться проанализировать его с помощью кода (следите за производительностью).

      class Foo { string MyField } //instead of int MyField
var result = await connection.QueryAsync<Foo>(sql);
Другие вопросы по тегам