我有这样的问题。我已经将Transaction服务添加到我的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运行程序,我收到错误,提交没有通过。像:
无法提交事务DB是否存在211
System.InvalidOperationException:已经有一个与此命令关联的打开的DataReader,必须先关闭它。
我正在学习C#中的编程,所以可能很容易识别错误。但不适合我。请帮忙。
在我添加交易服务之前,一切正常,我没有更改或添加任何查询或执行查询。请帮忙。
谢谢,迈克。
答案 0 :(得分:1)
主要问题是您使用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
正确处理(关闭)。
请注意,您的代码中仍有许多其他问题。例如:
result
是)