我写了这个方法,所以我不必每次都写开放连接等代码。
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;
}
我认为这应该可以正常工作,但最近我收到错误“读取器关闭时无效尝试调用MetaData”。现在我不确定为什么会出现这个错误。但这似乎是最可能的原因。已经有一段时间了,所以我无法确定错误是否是由这种方式引起的。一旦使用块结束,datareader是否保持为空?
答案 0 :(得分:1)
使用块结束后,datareader将关闭。 因此,任何从读取器读取数据的尝试都会引发异常。 请记住,datareader正在使用数据库连接。当连接关闭时(在您的using语句之后)将在SQLConnection上调用Dispose,从而使SqlDataReader无效/ null。
将代码放在using语句之外进行连接。
SqlConnection sqlConnection = SqlUtilities.CreateSqlConnection()
using(SqlCommand sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandText = commandText;
dataReader = sqlCommand.ExecuteReader (CommandBehavior.CloseConnection);
}
conn.Open();
success=true;
因为您已指定:
CommandBehavior.CloseConnection
当您关闭数据读取器时执行命令对象时,也将关闭与数据库的连接。
如果你想让你的函数返回一个datareader而不是boolean,你可以。这真的取决于你的偏好。但是,如果您返回datareader,则可以使用HasRows
或Read
方法进行检查。然后,您可以将datareader包装在using语句中,例如:
using (SqlDataReader myDataReader = GetMyDataReader())
{
//do something with the reader
}
在myDataReader
.Dispose()
的using语句结束时将自动调用。由于您使用.ExecuteReader()
在GetMyDataReader()
内部调用CommandBehavior.CloseConnection
,因此处理读取器也会关闭数据库连接。
答案 1 :(得分:1)
阅读帖子:ExecuteReader with CommanBehavior ( automatically close connection after reading data)
您收到错误是因为在使用USING
块时关闭了连接。
而不是这个设置命令行为
<强> CommandBehavior.CloseConnection 强>
将上述值作为参数传递给ExecuteReader
时关闭阅读器时无需关闭连接显式连接。
//无需关闭连接,只需编写即可 reader.Close();
将读者传递给另一种处理数据的方法时非常有用。