使用 Dapper 的 NextResult

Posted

技术标签:

【中文标题】使用 Dapper 的 NextResult【英文标题】:NextResult with Dapper 【发布时间】:2017-08-22 09:56:35 【问题描述】:

我正在使用带有 ClickHouse 数据库的 Dapper (https://clickhouse.yandex/)。这是分布式的面向列的数据库。它工作得很好,但是查询结果可以分成很多块,所以我应该使用 NextResult 来检索所有数据。 示例代码:

public static void ExecuteSQL(ClickHouseConnection connection, string sql)

    using (var reader = connection.CreateCommand(sql).ExecuteReader())
    
        do
        
            while (reader.Read())
            
                        ...
            
        
        while (reader.NextResult());
    

我正在尝试使用 Dapper。为了调用 NextResult 我应该使用 QueryMultiple 方法。我做了代码:

public static void ExecuteDapperQuery<T>(ClickHouseConnection connection, string sql)

    Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
    using (var dapperQuery = connection.QueryMultiple(sql))
    
        do
        
            var list = dapperQuery.Read<T>().ToList();
            ... /* Do something with list */
        
        while (true);
    

但是当检索到所有数据并且 SQL 读取器变为空时,此代码会引发异常 ObjectDisposedException。 我需要知道有没有办法知道我应该何时完成迭代?或者还有其他方法可以使用该数据库吗?

【问题讨论】:

它会抛出什么异常?你需要更具体。 这是因为无限的 do/while 循环。您只能为执行的语句数调用 read。 例外是ObjectDisposedException,当读者为空时发生。我不知道如何检查 NextResult 是否返回 true 或 false。 @Nkosi,我只有一条声明。 QueryMultiple 的原因是数据分成不同的块,不调用 NextResult 就无法检索。见第一个例子。 【参考方案1】:

这是因为无限的 do/while 循环。您只能为执行的语句数调用 read。

我需要知道有没有办法知道我应该何时完成迭代?

在阅读该集合之前检查以确保阅读器尚未被消耗

using (var gridReader = connection.QueryMultiple(sql)) 
    while(!gridReader.IsConsumed)  //<-- query multiple until consumed
        var list = gridReader.Read<T>().ToList();
        ... /* Do something with list */
    

【讨论】:

以上是关于使用 Dapper 的 NextResult的主要内容,如果未能解决你的问题,请参考以下文章

Dapper的新实践,Dapper.Contrib的使用与扩展

Dapper入门使用,代替你的DbSQLhelper

Dapper:安装Dapper时报错

.Net Core中Dapper的使用详解

dapper.net 转载

Dapper.Extension的基本使用