Returning the SqlDataReader
本文关键字:SqlDataReader the Returning | 更新日期: 2023-09-27 18:12:58
我正在尝试通过引用传递阅读器或返回一个阅读器。我在退货时遇到了问题。
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());
}
但是我得到以下错误
reader关闭时调用HasRows无效。
任何想法?
这就是问题所在:
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
将允许关闭阅读器以关闭连接。然而,它使其他事情变得棘手。例如,如果发生异常,您必须处理连接(因为这样调用者就没有机会了),否则而不是—我仍然喜欢我的方法。
John是对的,为什么你有问题,但你不需要传递一个连接。
我可以看到,你已经使用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循环中的代码将永远不会执行。
当出现异常时,仍然需要关闭连接,但是可以将close语句从finally in移到catch语句中。
catch (Exception ex)
{
conn.Dispose(); //Disposing closes the connection.
return null;
}
您可以尝试下面的示例http://msdn.microsoft.com/en-us/library/haa3afyz.aspx。
你不应该在使用reader之前调用close方法
Jon Skeet和Scott Chamberlain都是正确的。如果您希望保持自己的代码结构方式(与Jon Skeet的方法相反),则需要修改代码,以便在执行SqlCommand时发生错误时关闭连接。
public static SqlDataReader GetSql(string businessUnit, string taskId)
{
const string connstring = "Connection string";
SqlConnection conn = null;
SqlCommand command = null;
SqlDataReader reader = null;
try
{
conn = new SqlConnection(connstring);
command = new SqlCommand();
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);
conn.Open();
reader = command.ExecuteReader(CommandBehavior.CloseConnection);
conn = null;
return reader;
}
catch (Exception ex)
{
return null;
}
finally
{
if (conn != null) conn.Dispose();
if (command != null) command.Dispose();
}
}