请看下面两种方法。第一个返回一个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(使用前将#替换为@)