c# - System.InvalidOperationException -> 与此命令关联的 DataReader [提交事务失败]
问题描述
我有这样的问题。我已将事务服务添加到我的 SQL 类。当我想在执行后提交查询时出现错误。我将粘贴代码:
//SOME OF VARIABLES IN CLASS:
private SqlConnection connection;
private SqlCommand newQuery;
private SqlTransaction transaction;
private SqlDataReader result;
//BEGINNING TRANSACTION
public void BeginTransaction(string name)
{
try
{
transaction = connection.BeginTransaction(name);
}
catch
{
MessageBox.Show("Error while beginning transaction " + name);
}
}
//COMMIT TRANSACTION
public void Commit(string text)
{
try
{
transaction.Commit();
}
catch (Exception e)
{
MessageBox.Show("Couldn't commit transaction " + text + "\n\n" + e.ToString());
try
{
transaction.Rollback();
}
catch
{
MessageBox.Show("Couldn't Rollback transaction " + text);
}
}
transaction = null;
}
//EXECUTE QUERY METHOD
private SqlDataReader ExecuteQuery(string query)
{
try
{
if (connection.State == ConnectionState.Closed)
connection.Open();
if (result != null)
result.Close();
newQuery = connection.CreateCommand();
newQuery.CommandText = query;
newQuery.Transaction = transaction;
result = newQuery.ExecuteReader();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
return result;
}
//EXAMPLE FUNCTION WITH TRANSACTION, WHICH OCCURS ERROR:
public bool DoesDatabaseExist(string dbName)
{
BeginTransaction("DoesDatabaseExist");
bool res = ExecuteQuery("SELECT * FROM master.dbo.sysdatabases WHERE name='" + dbName + "';").HasRows;
Commit("Does DB Exist 211");
return res;
}
Afrer 运行程序,我得到错误,提交没有通过。喜欢:
无法提交事务数据库是否存在 211
System.InvalidOperationException:已经有一个打开的 DataReader 与此命令关联,必须先关闭。
我还在学习 C# 编程,所以可能很容易识别错误。但不适合我。请帮忙。
在我添加事务服务之前,一切正常,我没有更改或添加任何查询或查询执行。请帮忙。
谢谢,迈克。
解决方案
主要问题是您使用SqlDataReader
实例的方式。
您的第一个错误是将它作为类的一个字段:
private SqlDataReader result;
不要那样做(请删除该行)。
然后将函数更改为:
private SqlDataReader ExecuteQuery(string query)
{
try
{
if (connection.State == ConnectionState.Closed)
connection.Open();
newQuery = connection.CreateCommand();
newQuery.CommandText = query;
newQuery.Transaction = transaction;
var result = newQuery.ExecuteReader();
return result;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
throw;
}
}
这确保了上述函数的每次调用都返回它自己的SqlDataReader
.
好的,现在是来电者。您当前正在使用:
bool res = ExecuteQuery("SELECT * FROM master.dbo.sysdatabases WHERE name='" + dbName + "';").HasRows;
Commit("Does DB Exist 211");
这是不正确的,因为ExecuteQuery
返回的SqlDataReader
是您没有正确清理的。将其更改为:
var results = ExecuteQuery("SELECT * FROM master.dbo.sysdatabases WHERE name='" + dbName + "';");
using (results)
{
bool res = results.HasRows;
}
Commit("Does DB Exist 211");
这using
将确保SqlDataReader
正确处置(关闭)。
请注意,您的代码中仍然存在许多其他问题。例如:
推荐阅读
- angular - 如何在 Ionic 中构建此幻灯片
- c# - 注册后 SMTP 服务器不发送电子邮件
- robotframework - 机器人框架无法使用 timeout=20s
- android - 我希望使用我在 Android 中通过数组传递的警报管理器来通知不同时间
- swift - 如何使用 if else 语句将用户发送到 SwiftUI 中的其他页面视图
- apache-kafka - 我们如何将 kafka 主题转储到 presto
- javascript - 单击通知时,React-Native firebase 推送通知重定向到特定屏幕
- emacs - 如何覆盖 Emacs Org 模式 org-property-next-allowed-values 和 org-property-previous-allowed-value 的键绑定
- asp.net - 检测到无法访问的代码 [WebAPI]csharp(CS0162)
- c# - 如何在基于角色的授权 asp.net 中从数据库而不是 Web 配置中读取角色?