简体   繁体   中英

Access command object from SqlDataReader

Having a SqlDataReader object, I am trying to get the timeout of its related command. For example I am using this to create my SqlDataReader :

  SqlCommand myCommand = new SqlCommand(query, some_connection);
  _reader = myCommand.ExecuteReader();

In run-time using visual debugger I can access to this using :

 _reader.Command.CommandTimeout // Visual debugger 

No how can I do access this "property" in my code (I would like to expose this as a property for a third party lib)?

Context :

I am accessing the reader from a third library, so actually I just have access to the reader. My question is to understand why I can access the command in the debugger and not as a property? What is the mechanism behind the scene, some property extension, reflection?

You will need to use Reflection to get hold of the Command property, as it is set to internal access. This is what the debugger uses to show you the properties.

PropertyInfo prop = _reader.GetType().GetProperty("Command",
    BindingFlags.NonPublic | BindingFlags.Instance);

DbCommand cmd = (DbCommand)prop.GetValue(_reader);
int timeout = cmd.CommandTimeout;

PS You shouldn't really be unit testing third party components - that is the same as saying "I don't trust the .NET framework to do it's job so I'll check everything it's doing internally". If you want to test it, put the unit tests inside the third party solution.

I suggest to provide a facade (wrapper) for the SqlCommand and SqlConnection. Then pass this object to the third party library.

public class MyOwnReader : IDisposable
{
    bool isDisposed = false;

    SqlConnection _connection;
    SqlCommand _command;


    // You can expose the whole command, or specific property of the command
    public SqlCommand Command
    {
        get
        {
            return _command;
        }
    }


    public MyOwnReader(string connectionString)
    {
        _connection = new SqlConnection(connectionString);
        _connection.Open();
        _command = new SqlCommand();
        _command.Connection = _connection;
        _command.CommandType = CommandType.StoredProcedure; //example initialization
    }

    public void Dispose()
    {
        if (!isDisposed)
        {
            _connection.Dispose();
            _command.Dispose();

            isDisposed = true;
        }
    }

    public SqlDataReader ExecuteReader()
    {
        return _command.ExecuteReader();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM