gpt4 book ai didi

c# - SqlDataReader 已经在不同的命令中打开

转载 作者:太空宇宙 更新时间:2023-11-03 13:16:20 25 4
gpt4 key购买 nike

我遇到了一个有趣的错误,我想修复它。这是我的课,

public class SqlCommandWrapper
{
private readonly ISettings _settings;
private readonly ILogger _logger;

public SqlCommandWrapper(ISettings settings, ILogger logger)
{
_settings = settings;
_logger = logger;
}

private enum ExecutionType
{
Reader,
NonQuery,
Scaler

}

public async Task<SqlDataReader> ExecuteReaderAsync(string commandText, params SqlParameter[] parameters)
{
return (SqlDataReader)await ExecuteAsync(ExecutionType.Reader, CommandType.StoredProcedure, commandText, IsolationLevel.ReadUncommitted, parameters).ConfigureAwait(false);
}

public async Task<SqlDataReader> ExecuteReaderAsync(CommandType commandType, string commandText, IsolationLevel isolationLevel,
params SqlParameter[] parameters)
{
return (SqlDataReader)await ExecuteAsync(ExecutionType.Reader, commandType, commandText, isolationLevel, parameters).ConfigureAwait(false);
}

public async Task<SqlDataReader> ExecuteReaderAsync(CommandType commandType, string commandText, params SqlParameter[] parameters)
{
return
(SqlDataReader)
await ExecuteAsync(ExecutionType.Reader, commandType, commandText, IsolationLevel.ReadUncommitted, parameters).ConfigureAwait(false);
}

public async Task<int> ExecuteNonQueryAsync(string commandText, params SqlParameter[] parameters)
{
return (int)await ExecuteAsync(ExecutionType.NonQuery, CommandType.StoredProcedure, commandText, IsolationLevel.ReadUncommitted, parameters).ConfigureAwait(false);
}

public async Task<int> ExecuteNonQueryAsync(CommandType commandType, string commandText, IsolationLevel isolationLevel, params SqlParameter[] parameters)
{
return (int) await ExecuteAsync(ExecutionType.NonQuery, commandType, commandText, isolationLevel, parameters).ConfigureAwait(false);
}

public async Task<int> ExecuteNonQueryAsync(CommandType commandType, string commandText, params SqlParameter[] parameters)
{
return (int) await ExecuteAsync(ExecutionType.NonQuery, commandType, commandText, IsolationLevel.ReadUncommitted, parameters).ConfigureAwait(false);
}

public Task<object> ExecuteScalarAsync(string commandText, params SqlParameter[] parameters)
{
return ExecuteAsync(ExecutionType.Scaler, CommandType.StoredProcedure, commandText, IsolationLevel.ReadUncommitted, parameters);
}

public Task<object> ExecuteScalarAsync(CommandType commandType, string commandText, IsolationLevel isolationLevel, params SqlParameter[] parameters)
{
return ExecuteAsync(ExecutionType.Scaler, commandType, commandText, isolationLevel, parameters);
}

public Task<object> ExecuteScalarAsync(CommandType commandType, string commandText, params SqlParameter[] parameters)
{
return ExecuteAsync(ExecutionType.Scaler, commandType, commandText, IsolationLevel.ReadUncommitted, parameters);
}


private async Task<object> ExecuteAsync(ExecutionType executionType, CommandType commandType, string commandText, IsolationLevel isolationLevel,
params SqlParameter[] parameters)
{
using (var connection = new SqlConnection(_settings.DatabaseConnectionString))
{
using (var command = new SqlCommand(commandText, connection) {CommandType = commandType})
{
command.Parameters.AddRange(parameters);
command.CommandTimeout = _settings.CommandTimeout;
await connection.OpenAsync().ConfigureAwait(false);
var transaction = connection.BeginTransaction(isolationLevel);
command.Transaction = transaction;
try
{
object result;
switch (executionType)
{
case ExecutionType.Reader:
result = await command.ExecuteReaderAsync().ConfigureAwait(false);
break;
case ExecutionType.NonQuery:
result = await command.ExecuteNonQueryAsync().ConfigureAwait(false);
break;
default:
result = await command.ExecuteScalarAsync().ConfigureAwait(false);
break;
}
transaction.Commit();
return result;
}
catch (Exception exception)
{
_logger.Log(exception);
transaction.Rollback();
throw;
}
}
}
}
}

我称它为

using (var reader = await _sqlCommandWrapper.ExecuteReaderAsync("MySP", parameters))
{
// My code
}

当我运行我的类(class)时,我收到一个错误:

There is already an open DataReader associated with this Command which must be closed first.

最佳答案

我通过添加回调方法来修复它,

public class SqlCommandWrapper
{
private readonly ISettings _settings;
private readonly ILogger _logger;

public SqlCommandWrapper(ISettings settings, ILogger logger)
{
_settings = settings;
_logger = logger;
}

public enum ExecutionType
{
Reader,
NonQuery,
Scaler
}

public Task<IEnumerable<T>> ExecuteReaderAsync<T>(string commandText, Func<IDataReader, T> callback, params SqlParameter[] parameters)
{
return ExecuteReaderAsync(CommandType.StoredProcedure, commandText, callback, parameters);
}

public Task<IEnumerable<T>> ExecuteReaderAsync<T>(CommandType commandType, string commandText, Func<IDataReader, T> callback, params SqlParameter[] parameters)
{
return ExecuteReaderAsync(ExecutionType.Reader, commandType, commandText, IsolationLevel.ReadUncommitted, callback, parameters);
}

public async Task<IEnumerable<T>> ExecuteReaderAsync<T>(ExecutionType executionType, CommandType commandType, string commandText, IsolationLevel isolationLevel,
Func<IDataReader, T> callback, params SqlParameter[] parameters)
{
return (IEnumerable<T>)await ExecuteAsync(executionType, commandType, commandText, isolationLevel, parameters, callback).ConfigureAwait(false);
}

public Task<int> ExecuteNonQueryAsync(string commandText, params SqlParameter[] parameters)
{
return ExecuteNonQueryAsync(CommandType.StoredProcedure, commandText, parameters);
}

public Task<int> ExecuteNonQueryAsync(CommandType commandType, string commandText, params SqlParameter[] parameters)
{
return ExecuteNonQueryAsync(ExecutionType.NonQuery, commandType, commandText, IsolationLevel.ReadUncommitted, parameters);
}

public async Task<int> ExecuteNonQueryAsync(ExecutionType executionType, CommandType commandType, string commandText, IsolationLevel isolationLevel, params SqlParameter[] parameters)
{
return (int)await ExecuteAsync(executionType, commandType, commandText, isolationLevel, parameters).ConfigureAwait(false);
}

public Task<object> ExecuteScalarAsync(string commandText, params SqlParameter[] parameters)
{
return ExecuteScalarAsync(CommandType.StoredProcedure, commandText, parameters);
}

public Task<object> ExecuteScalarAsync(CommandType commandType, string commandText, params SqlParameter[] parameters)
{
return ExecuteScalarAsync(ExecutionType.Scaler, commandType, commandText, IsolationLevel.ReadUncommitted, parameters);
}

public Task<object> ExecuteScalarAsync(ExecutionType executionType,CommandType commandType, string commandText, IsolationLevel isolationLevel, params SqlParameter[] parameters)
{
return ExecuteAsync(executionType, commandType, commandText, isolationLevel, parameters);
}

private Task<object> ExecuteAsync(ExecutionType executionType, CommandType commandType, string commandText, IsolationLevel isolationLevel,
SqlParameter[] parameters)
{
return ExecuteAsync<object>(executionType, commandType, commandText, isolationLevel, parameters);
}

private async Task<object> ExecuteAsync<T>(ExecutionType executionType, CommandType commandType, string commandText, IsolationLevel isolationLevel, SqlParameter[] parameters, Func<IDataReader, T> callback = null)
{
using (var connection = new SqlConnection(_settings.DatabaseConnectionString))
{
using (var command = new SqlCommand(commandText, connection) {CommandType = commandType})
{
command.Parameters.AddRange(parameters);
command.CommandTimeout = _settings.CommandTimeout;
await connection.OpenAsync().ConfigureAwait(false);
var transaction = connection.BeginTransaction(isolationLevel);
command.Transaction = transaction;
try
{
object result;
switch (executionType)
{
case ExecutionType.Reader:
var reader = await command.ExecuteReaderAsync().ConfigureAwait(false);
using (reader)
{
var list = new List<T>();
while (reader.Read())
{
if (callback != null)
{
list.Add(callback(reader));
}
}
result = list;
}
break;
case ExecutionType.NonQuery:
result = await command.ExecuteNonQueryAsync().ConfigureAwait(false);
break;
default:
result = await command.ExecuteScalarAsync().ConfigureAwait(false);
break;
}
transaction.Commit();
return result;
}
catch (Exception exception)
{
_logger.Log(exception);
transaction.Rollback();
throw;
}
}
}
}
}

用法,

  (await _sqlCommandWrapper.ExecuteReaderAsync("MySP", r =>
new Product
{
Id = (int) r["Id"],
........................
........................
........................

}, parameters)).ToList()

关于c# - SqlDataReader 已经在不同的命令中打开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25976103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com