在 Dapper 中调用 QueryAsync 抛出 System.Data.DataException

Calling QueryAsync in Dapper throws System.Data.DataException

我正在尝试使用 Dapper 查询一个 Sqlite table,它看起来像这样:

CREATE TABLE "Running" (
    "Id"    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    "MachineName"   BLOB NOT NULL DEFAULT 'machine' UNIQUE,
    "IsOnline"  INTEGER DEFAULT 0,
    "TimesRan"  INTEGER DEFAULT 0,
    "LoginDateTime" TEXT,
    "LogoutDateTime"    TEXT,
    "ForceUpgrade"  INTEGER NOT NULL DEFAULT 0,
    "Version"   TEXT
)

目前在那table我只有一条记录:

1 台式机-KQT7CGC 0<br> 1<br> 2019-09-21 03:04:10.099067<br> 2019-09-21 03:04:37.6825109 0<br> 4.0.0

var data = await _globalConfig.Connection.GetStatusAsync();

    public async Task<List<ApplicationInfoModel>> GetStatusAsync()
    {
        using (IDbConnection cnn = new SQLiteConnection(ConfigurationManager.GetLocalOrSharedConnectionString(), true))
        {
            var output = await cnn.QueryAsync<ApplicationInfoModel>("select * from Running", new DynamicParameters());

            return output.ToList();
        }
    }

ApplicationInfoModel 看起来像这样:

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

    public string MachineName { get; set; }

    public bool IsOnline { get; set; }

    public int TimesRan { get; set; }

    public DateTime LoginDateTime { get; set; } = DateTime.Now;

    public DateTime LogoutDateTime { get; set; }

    public bool ForceUpgrade { get; set; }

    public string Version { get; set; }

}

我收到 System.Data.DataException 消息 Error parsing column 1 (MachineName=System.Byte[] - Object)

调用堆栈如下:

   at Dapper.SqlMapper.ThrowDataException(Exception ex, Int32 index, IDataReader reader, Object value) in C:\projects\dapper\Dapper\SqlMapper.cs:line 3633
   at Dapper.SqlMapper.<QueryAsync>d__33`1.MoveNext() in C:\projects\dapper\Dapper\SqlMapper.Async.cs:line 439
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SdeHelper.Library.Main.DataAccess.SQLiteConnector.<GetStatusAsync>d__11.MoveNext() in G:\Users\mdumi\GitRepos\sdehelper\SdeHelper.Library.Main\DataAccess\SQLiteConnector.cs:line 154
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SdeHelper.WpfUI.Framework.Helpers.ApplicationManager.<StartApplication>d__3.MoveNext() in G:\Users\mdumi\GitRepos\sdehelper\SdeHelper.WpfUI.Framework\Helpers\ApplicationManager.cs:line 39

以及内部异常:

Message: Object must implement IConvertible.

   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at System.Convert.ChangeType(Object value, Type conversionType)

谁能帮我理解为什么我应该在模型上实现 IConvertible

我尝试只为 MachineName 属性 实现 IConvertible,但它仍然抛出相同的异常。

在这种特定情况下 对象必须实现 IConvertible 内部异常意味着 Dapper 无法自动将您的 MachineName 数据库字段从数据库类型 BLOB 到模型类型 string

您应该将数据库类型 TEXT 用于 MachineName 列(这应该是正确的选择)或将其转换为 SQL selectTEXT 适当地。像这样:

select cast(MachineName AS TEXT), IsOnline, TimesRan, LoginDateTime, LogoutDateTime, ForceUpgrade, Version from Running

这两个选项都应该可以解决您当前的异常问题。

有关转换为 TEXT 的更多信息,请参见此处:Sqlite: How to cast(data as TEXT) for BLOB