Использование объекта, созданного другим способом - PullRequest
1 голос
/ 25 октября 2019

Я пытаюсь сделать общий вызов 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 и неутилизировать.

Ответы [ 2 ]

4 голосов
/ 25 октября 2019

Вы можете сделать это, передав Действие следующим образом:

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 голос
/ 25 октября 2019

Можно использовать объект, созданный в другом методе, в операторе using. Однако в вашем случае вы используете SqlDataReader, который использует SqlConnection, который расположен в конце вызова ExecuteSql.

Как объяснено здесь , вам нужнодопустимый объект подключения для использования SqlDataReader

...