我写了这个方法,这样我就不必每次都写打开连接等代码。
public static bool TryExecuteReader(string commandText,string functionNameForLogging, string errorText, out SqlDataReader dataReader)
{
bool success = false;
dataReader = null;
try
{
using (SqlConnection sqlConnection = SqlUtilities.CreateSqlConnection())
{
sqlConnection.Open();
SqlCommand sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = commandText;
dataReader = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection);
}
success = true;
}
catch (Exception ex)
{
SqlUtilities.LogError(functionNameForLogging,ex.Message,-1);
}
return success;
}
我认为这应该工作得很好,但最近我得到错误"无效尝试调用元数据时,阅读器关闭"。现在我不确定为什么会发生这个错误。但这似乎是最可能的原因。已经有一段时间了,所以我不能确定这个错误是否是由这种方式引起的。一旦使用块结束,数据读取器是否仍然为空?
using块结束后,数据读取器关闭。因此,任何从读取器读取数据的尝试都会抛出异常。请记住,数据读取器正在使用数据库连接。当连接关闭时(在using语句之后),将调用SQLConnection上的Dispose,从而使SqlDataReader为空。
把你的代码放在using语句之外,像这样。
SqlConnection sqlConnection = SqlUtilities.CreateSqlConnection()
using(SqlCommand sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandText = commandText;
dataReader = sqlCommand.ExecuteReader (CommandBehavior.CloseConnection);
}
conn.Open();
success=true;
因为您指定了:
CommandBehavior.CloseConnection
当您在关闭数据阅读器的那一刻执行命令对象时,与数据库的连接也将关闭。
如果你想让函数返回一个数据读取器而不是一个布尔值,你可以这样做。这取决于你的喜好。但是如果你返回一个数据阅读器,你可以用HasRows
或Read
方法检查。然后可以将数据读取器包装在using语句中,例如:
using (SqlDataReader myDataReader = GetMyDataReader())
{
//do something with the reader
}
在myDataReader
的using语句结束时,将自动调用.Dispose()
。由于您在GetMyDataReader()
中使用CommandBehavior.CloseConnection
调用.ExecuteReader()
,那么处置读取器也将关闭您的数据库连接。
Read the post: ExecuteReader with CommanBehavior(读取数据后自动关闭连接)
你得到一个错误,因为你正在关闭连接时使用USING
块。
而不是设置命令行为
-
CommandBehavior。CloseConnection
当您将上述值作为参数传递给ExecuteReader
时当你关闭阅读器时,不需要显式关闭连接。
//不需要关闭连接,只需要写入reader.Close ();
在将reader传递给另一个方法处理数据时非常有用。