我使用using
发表以下声明:
using (var reader = data.CreateCommand(sql).ExecuteDataReader())
在这种情况下data
是一个内部持有SqlConnection
的对象。 CreateCommand(sql)
函数返回SqlCommand
,ExecuteDataReader
返回SqlDataReader
。由于SqlCommand
和SqlDataReader
都是IDisposable
,它们是否都会被using
语句使用?
现在我这样做了:
using (var cmd = data.CreateCommand(sql))
using (var reader = cmd.ExecuteDataReader())
但我想知道是否可以将它们组合起来如上所述?
答案 0 :(得分:3)
同意Matthew Watson的评论。您需要同时拥有两个End Sub
州。
以下是相关问题和其他推理。 SqlConnection SqlCommand SqlDataReader IDisposable
答案 1 :(得分:3)
“如果可以将它们组合起来” - 两个using
完全没问题,因为两者都需要处理。
您可以通过提取方法将它们组合在一起:
void RunWithReader(string sql, Action<SQLDataReader> action)
{
using (var cmd = data.CreateCommand(sql))
using (var reader = cmd.ExecuteDataReader())
action(reader);
}
然后你可以使用lambda
RunWithReader("whatever command", reader =>
{
... // while(reader.Read() { ... } - this could also be extracted
});
答案 2 :(得分:1)
您展示代码的方式内部IDisposable
(IDbCommand
)未被处理。
您有两种选择:
你可以把它全部放在一个using
中,如下所示:
using (IDisposable cmd = data.CreateCommand(), reader = ((IDbCommand)cmd).ExecuteReader())
{
// code here
}
但这很麻烦。另一个选项是嵌套的using
语句:
using (var cmd = data.CreateCommand())
{
using (var reader = cmd.ExecuteReader())
{
// code here
}
}
除此之外,你可能会有点复杂,并编写一个扩展方法来帮助(排序)为你清理它。
public static class Ex
{
public static void Using<T, R>(this T obj, Func<T, R> create, Action<T, R> use) where R : IDisposable
{
using (var d = create(obj))
{
use(obj, d);
}
}
}
然后你可以这样做:
data.Using(d => d.CreateCommand(), (d, c) => c.Using(c2 => c2.ExecuteReader(), (c3, r) =>
{
// code here
}));
但也许这并没有太大改善。