我正在尝试进行通用SQL调用,这使我提出了一个有趣的问题。我有一个执行SQL并返回SQLDataReader
的方法。
private SqlDataReader ExecuteSql(SqlCommand command)
{
using (var connection = new SqlConnection(ConnectionText, Credentials))
{
command.Connection = connection;
connection.Open();
return command.ExecuteReader();
}
}
调用命令获取读取器并正确处理返回的数据。但是,在知道需要丢弃读者的情况下,我将其包含在using
语句中。
using (SqlDataReader reader = ExecuteSql(command))
{
while (reader.Read())
{
try { ... }
catch(Exception e) { ... }
}
}
我认为Dispose
应当在SqlDataReader
语句的末尾在using
上调用,尽管它在代码中的创建位置。但是,我还找不到任何可以证实这一点的东西。
概括地说,using
语句可以成功地在代码中其他位置创建的对象上使用吗?
作为旁注,我确实意识到,如果SqlDataReader
是在ExecuteSql
方法中创建为对象而不是直接返回的,那么在运行时可能会引发异常ExecuteSql
方法,并且不会被丢弃。
答案 0 :(得分:4)
您可以通过以下操作来完成此操作:
private void ExecuteSql(SqlCommand command, Action<SqlDataReader> action)
{
using (var connection = new SqlConnection(ConnectionText, Credentials))
{
command.Connection = connection;
connection.Open();
using (var reader = command.ExecuteReader())
{
action(reader);
}
}
}
然后调用函数:
var myCommand = //...
int id;
ExecuteSql(myCommand, (reader) => {
id = reader.GetInt32(0);
});
现在,任何调用者都无需知道是否必须处置它,并且该方法在读取器上完成工作后,您的连接也将被处置。
答案 1 :(得分:1)
可以在using语句中使用在另一个方法中创建的对象。
但是,根据您的情况,您使用的SqlDataReader
使用的是SqlConnection
调用末尾的ExecuteSql
。
如here所述,您需要一个有效的连接对象才能使用SqlDataReader