使用SqlDataReader作为资源的习惯用法

Pau*_*rth 3 .net c# sql sql-server

这个问题之后,我发现自己一遍又一遍地编写以下代码:

SqlCommand command = new SqlCommand();
// Code to initialize command with what we want to do
using (SqlConnection connection = openConnection())
{
    command.Connection = connection;
    using (SqlDataReader dataReader = thisCommand.ExecuteReader())
    {
        while (dataReader.Read())
        {
            // Do stuff with results
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

必须嵌套两个using语句是相当繁琐的.有没有办法告诉 SqlDataReader它拥有该命令,并告诉命令它拥有该连接?

如果有办法做到这一点,那么我可以编写一个可以这样调用的辅助方法:

// buildAndExecuteCommand opens the connection, initializes the command
// with the connection and returns the SqlDataReader object. Dispose of the
// SqlDataReader to dispose of all resources that were acquired
using(SqlDataReader reader = buildAndExecuteCommand(...))
{
    // Do stuff with reader
}
Run Code Online (Sandbox Code Playgroud)

或者我必须咬紧牙关并在SqlDataReader上编写自己的包装器?

Jon*_*eet 7

有一件事就是编写一个为您处理的方法,并使用每个结果回调一个委托.例如:

using (SqlConnection connection = openConnection())
{
    command.Connection = connection;
    ExecuteReaderWithCommand(command, reader =>
    {
        // Do stuff with the result here.
    });
}
Run Code Online (Sandbox Code Playgroud)

然后ExecuteReaderWithCommand将是这样的:

public static void ExecuteReaderWithCommand(SqlCommand command,
    Action<SqlDataReader> action)
{
    using (SqlDataReader dataReader = thisCommand.ExecuteReader())
    {
        while (reader.Read())
        {
            action(reader);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你愿意,你可以将它作为扩展方法SqlCommand.哎呀,如果你想要的话,你可以去城里让它为你打开连接......你越能抽象出"打开/使用/关闭"的想法,就越好.