【问题标题】:Calling QueryAsync in Dapper throws System.Data.DataException在 Dapper 中调用 QueryAsync 会引发 System.Data.DataException
【发布时间】:2019-09-24 17:02:59
【问题描述】:

我正在尝试使用 Dapper 查询一个如下所示的 Sqlite 表:

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
)

目前在那张表中我只有一条记录:

1 DESKTOP-KQT7CGC 0
1
2019-09-21 03:04:10.099067
2019-09-21 03:04:37.6825109 0
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,但它仍然抛出相同的异常。

【问题讨论】:

    标签: c# dapper iconvertible


    【解决方案1】:

    在这种特定情况下对象必须实现 IConvertible 内部异常意味着 Dapper 无法自动将您的 MachineName DB 字段从 DB 类型 BLOB 转换为模型类型 @987654324 @

    您应该将 DB 类型 TEXT 用于 MachineName 列(据说这是正确的选择)或将其正确转换为 SQL selectto TEXT。像这样:

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

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

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

    【讨论】:

    • 这解决了我的问题,不知何故,我似乎不小心将数据库中字段 MachineName 的类型从 Text 更改为 Blob。
    猜你喜欢
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 1970-01-01
    相关资源
    最近更新 更多