如何使用 SqlDataReader 返回和使用 IAsyncEnumerable

2024-05-05

请看下面两种方法。第一个返回一个IAsyncEnumerable。第二个试图消耗它。

using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;

public static class SqlUtility
{
    public static async IAsyncEnumerable<IDataRecord> GetRecordsAsync(
        string connectionString, SqlParameter[] parameters, string commandText,
        [EnumeratorCancellation]CancellationToken cancellationToken)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
            using (SqlCommand command = new SqlCommand(commandText, connection))
            {
                command.Parameters.AddRange(parameters);
                using (var reader = await command.ExecuteReaderAsync()
                    .ConfigureAwait(false))
                {
                    while (await reader.ReadAsync().ConfigureAwait(false))
                    {
                        yield return reader;
                    }
                }
            }
        }
    }

    public static async Task Example()
    {
        const string connectionString =
            "Server=localhost;Database=[Redacted];Integrated Security=true";
        SqlParameter[] parameters = new SqlParameter[]
        {
            new SqlParameter("VideoID", SqlDbType.Int) { Value = 1000 }
        };
        const string commandText = "select * from Video where VideoID=@VideoID";
        IAsyncEnumerable<IDataRecord> records = GetRecordsAsync(connectionString,
            parameters, commandText, CancellationToken.None);
        IDataRecord firstRecord = await records.FirstAsync().ConfigureAwait(false);
        object videoID = firstRecord["VideoID"]; //Should be 1000.
        // Instead, I get this exception:
        // "Invalid attempt to call MetaData when reader is closed."
    }
}

当代码尝试读取结果时IDataReader (at object videoID = firstRecord["VideoID"];),我得到这个异常:

阅读器关闭时调用元数据的尝试无效。

这是因为SqlDataReader被处置。有人可以提供推荐的枚举方法吗SqlDataReader以异步方式以便每个结果记录都可供调用方法使用?谢谢。


在这种情况下,LINQ 不是你的朋友,因为FirstAsync将关闭迭代器before它返回的结果不是 ADO.NET 所期望的;基本上:不要在这里使用 LINQ,或者至少:不要以这种方式使用。你也许可以使用类似的东西Select执行投影当序列仍然开放时,或者将这里的所有工作转移到像 Dapper 这样的工具可能会更容易。或者,手动执行此操作:

await foreach (var record in records)
{
    // TODO: process record
    // (perhaps "break"), because you only want the first
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 SqlDataReader 返回和使用 IAsyncEnumerable 的相关文章

随机推荐

  • php中的可变长度数据包

    我正在接收通过 UDP 发送到我的服务器的数据包 我正在使用 socket read 来读取数据 它运行得很好 但是我遇到了一个错误 在我的例子中 socket read 的长度参数并不总是相同的 数据长度的范围可以是 50 150 字节
  • C [x ... y] 范围赋值

    今天我遇到了一些代码 这些代码使用了我多年来进行 C 编程时从未见过的语法 MWE include
  • .htaccess 只允许访问包含文件

    我的网站上有各种子文件夹 我希望用户无法通过 URL 访问它们 但同时我的主要 PHP 文件能够包含它们或将它们用作表单或链接上的操作 我尝试使用 htaccess 与
  • Mongo聚合查询结果在较少的文档中排序

    我在查询我们的一个馆藏时遇到了一个奇怪的问题将结果聚合到另一个集合中 https stackoverflow com a 25936760 1746118 我正在查询已执行某些操作的唯一用户 并在聚合查询中预测每个用户执行的操作计数 var
  • 将 stdin 传递到 Unix 主机或 dig 命令

    假设我有一个 IP 列表进入我正在跟踪的日志中 1 1 1 1 1 1 1 2 1 1 1 3 我想轻松地将它们解析为主机名 我希望能够 tail f access log host 由于主机无法以这种方式理解来自标准输入的输入 因此会失败
  • Alamofire 使用公共键和多个值传递参数?

    我需要在我的项目中执行此操作 如果我手动将字符串附加到 Alamofire 中的 URL 我可以轻松完成此操作 但我不希望这样做 我想要的参数为范围 object 参数的一个公共键中有多个值 我一直在做什么 public func find
  • Prestashop 1.6 自定义模块未显示在前端

    我的模块没有显示在前端 我按照这个链接 doc prestashop com display PS15 Creating a PrestaShop module 在 prestashop 1 6 中创建自定义模块 我已经检查了位置 清除并禁
  • 如何防止脚本注入攻击

    Intro 这个话题一直是 StackOverflow 以及许多其他技术论坛上许多问题和答案的祸根 然而 其中大多数都是特定于具体条件的 甚至更糟 通过脚本注入预防中的 整体 安全性dev tools console or dev tool
  • time() 会返回相同的输出吗?

    当用户注册时 我正在为 PHP 中的用户生成令牌 我想知道两个用户是否可以获得相同的令牌 因为这会破坏系统 请让我知道这是否足够 token md5 rand time 编辑 我现在正在使用我在另一个问题上找到的generate uuid
  • 使用另一个索引数组正确索引多维 Numpy 数组

    我正在尝试索引多维数组P与另一个数组indices 它指定我想要沿最后一个轴的哪个元素 如下所示 import numpy as np M N 20 10 P np random rand M N 2 9 index into the la
  • sqlite 3“SQL 错误‘内存不足’(7)”objc

    嗨 有人可以指出我做错了什么吗 错误是这样的 SQL error out of memory 7 NSArray RecipeInfo NSMutableArray retval NSMutableArray alloc init NSSt
  • WebGL:enablevertexattribarray索引超出范围

    这是我的顶点和片段着色器
  • PHP:如何删除“[”和“]”之间的字符串

    我需要删除 内的字符串 包括 本身 我尝试从该网站寻找解决方案 我有一个线索 我应该尝试使用 preg replace 进行一些操作 但它对我来说似乎太专业了 例如 gallery ids 92 93 94 95 96 97 98 99 1
  • 通过易失性引用/指针访问声明的非易失性对象是否会为所述访问赋予易失性规则?

    这将是一篇很长的文章 为了将其置于上下文中并提供尽可能多的信息 我必须浏览各种链接和引用 这通常是我们进入 C C 标准兔子洞的唯一方法 如果您对这篇文章有更好的引用或任何其他改进 请告诉我 但先总结一下 你可以责怪 zwol对我来说发布这
  • 如何对 MySQL 数据库中的 ENUM 列进行排序?

    I have colorMySQL 表中的列类型为ENUM RED YELLOW MY COLOR BLACK 还有另一个name列的类型是VARCHAR 30 我想按以下顺序获取所有表行 YELLOW首先行 排序依据name RED最后一
  • 将numpy字符串数组转换为int数组[重复]

    这个问题在这里已经有答案了 我有一个 numpy ndarray a 0 99 0 56 0 56 2 02 0 96 如何将其转换为int 输出 a 0 99 0 0 0 56 0 56 2 02 0 96 我想要 0 0 代替空白 im
  • 使用 Javascript 从 URL 字符串获取端口 [重复]

    这个问题在这里已经有答案了 我想要一个 javascript 函数 它将获取一个 url 作为参数 并返回该 URL 的端口 如下所示 如果有一个http or https 端口 80 443 它不会显示在 url 结构中 但我还是希望它们
  • Codeigniter:对未定义函数 mysqli_init() 的致命错误调用

    我刚刚更改了服务器并遇到以下错误 Fatal error Call to undefined function mysqli init in home blacktwitter public html system database dri
  • 更改 AS3 中的 TextField 选择颜色

    如何更改 ActionScript 3 中 TextField 的选择 突出显示 颜色 我有一个输入文本字段 黑色背景上有白色文本 因此 选择是不可见的 这对于可用性来说非常糟糕 谢谢 另一种方法是使用文本布局框架 特别是使用 Select
  • 如何使用 SqlDataReader 返回和使用 IAsyncEnumerable

    请看下面两种方法 第一个返回一个IAsyncEnumerable 第二个试图消耗它 using System Collections Generic using System Data using System Data SqlClient