我正试图以参考的方式传递一位读者或让一位读者返回。我在回来的时候对它有意见。
public static SqlDataReader GetSql(string businessUnit, string taskId)
{
const string connstring = "Connection string";
SqlConnection conn = new SqlConnection(connstring);
SqlCommand command = new SqlCommand();
SqlDataReader reader;
try
{
conn.Open();
command.Connection = conn;
command.CommandType = CommandType.Text;
command.CommandText =
"SELECT * FROM Audits WHERE BusinessUnit = @BU AND TaskID = @TID";
command.Parameters.AddWithValue("@BU", businessUnit);
command.Parameters.AddWithValue("@TID", taskId);
return reader = command.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception ex)
{
return null;
}
finally
{
conn.Close();
}
}
SqlDataReader reader = QaqcsqlLib.GetSql("job", "Task1");
if (reader.HasRows)
{
while (reader.Read())
MessageBox.Show(reader[0].ToString());
}但是我得到了以下错误
关闭读取器时调用HasRows的尝试无效。
有什么想法吗?
发布于 2013-05-09 18:18:46
这就是问题所在:
finally
{
conn.Close();
}在方法返回之前关闭连接。如果没有打开的连接,读者将无法正常工作。
(考虑到只有在返回时才使用reader变量,所以不清楚为什么要使用它。)
在打开连接的方法中返回SqlDataReader通常很棘手,因为这意味着您没有一种很好的关闭连接的方法。最好是让调用方传入连接,此时您可以拥有:
using (var connection = new SqlConnection(...))
{
using (var reader = QaqcsqlLib.GetSql(connection, "job", "Task1"))
{
// Use the reader here
}
}编辑:正如Scott所指出的,使用CommandBehavior.CloseConnection将允许关闭读取器以关闭连接。然而,它使其他事情变得更加棘手。例如,如果出现异常(因为调用方将没有机会),则必须释放连接,但不是其他--我仍然更喜欢我的方法。
发布于 2013-05-09 19:01:29
约翰是对的关于为什么会出现问题,但不需要传递连接。
我可以看到,在启动读取器并传入SqlCommand.ExecuteReader(CommandBehavior)时,您已经在使用CommandBehavior.CloseConnection重载。然而,您所做的错误是您从未处理从您的函数返回的读取器。删除finally块,然后将返回的读取器包装到using块中。这将在退出块时为您关闭底层连接(因为您在CommandBehavior.CloseConnection中传递)。
using(SqlDataReader reader = QaqcsqlLib.GetSql("job", "Task1"))
{
while (reader != null && reader.Read()) //Added null check as your GetSql could return null.
MessageBox.Show(reader[0].ToString());
}我还去掉了reader.HasRows,因为它是不必要的。如果没有返回的结果,那么对reader.Read()的第一次调用将返回false,并且while循环中的代码将永远不会执行。
当出现异常时,仍然需要关闭连接,但是可以将关闭从finally in移到catch。
catch (Exception ex)
{
conn.Dispose(); //Disposing closes the connection.
return null;
}发布于 2013-05-09 18:20:20
您可以尝试遵循下一个示例http://msdn.microsoft.com/en-us/library/haa3afyz.aspx。
在使用您的读取器之前,不应该调用close方法。
https://stackoverflow.com/questions/16468379
复制相似问题