2014-03-31 3 views
1

Я столкнулся с ошибкой при получении чего-то из базы данных Oracle.OracleDataReader. Ошибка: неверная операция. Соединение закрыто

Вот мой код:

public virtual IDataReader LoadDataReaderWithSqlString(string strQuery, ISessionScope session) 
    { 
     var s = GetSession(session); 
     using (var connection = s.Connection) 
     { 
      var command = connection.CreateCommand(); 
      command.Connection = connection; 
      if (connection.State == ConnectionState.Closed || connection.State == ConnectionState.Broken) 
       connection.Open(); 
      command.CommandType = CommandType.Text; 
      command.CommandText = s.CreateSQLQuery(strQuery).ToString(); 
      s.Transaction.Enlist(command); // Set the command to exeute using the NHibernate's transaction 
      using (var dataReader = command.ExecuteReader()) 
      { 
       if(dataReader.Read()) 
        return dataReader; 
      } 
     } 
     return null; 
    } 

Когда я отладки, я был в состоянии видеть возвращаемое значение в DataReader. Я использую NHibernate для запуска Raw SQL. Я хочу вернуть DataReader. Кто-нибудь может мне помочь?

ответ

0

это потому, что вы имея

using (var connection = s.Connection) и using (var dataReader = command.ExecuteReader())

using блок будет располагать объект (здесь connection и dataReader)

удалить с помощью блока, если вам нужно вернуть dataReader

3

Вы пытаетесь вернуться открыто IDataReader? Проблема в том, что вы завершаете свой ExecuteReader в заявлении using. using означает, что ваш dataReader будет удален после того, как будет выполнен код внутри using. Таким образом, вы возвращаете расположенный объект. Решение: удалить using:

var dataReader = command.ExecuteReader(); 
if(dataReader.Read()) 
    return dataReader; 

И так же для подключения объекта.

ADD

Как уже упоминалось Дэвид в комментариях вы можете избежать утечки ресурсов (я имею в виду тот случай, когда было открыто соединение, но команда не была выполнена), то вы должны обрабатывать исключения, как это:

public virtual IDataReader LoadDataReaderWithSqlString(string strQuery, ISessionScope session) 
{ 
    try 
    { 
     var s = GetSession(session); 
     var connection = s.Connection; 

     var command = connection.CreateCommand(); 
     command.Connection = connection; 
     if (connection.State == ConnectionState.Closed || connection.State == ConnectionState.Broken) 
      connection.Open(); 

     command.CommandType = CommandType.Text; 
     command.CommandText = s.CreateSQLQuery(strQuery).ToString(); 
     s.Transaction.Enlist(command); // Set the command to exeute using the NHibernate's transaction 

     try 
     { 
      var dataReader = command.ExecuteReader(); 
      if(dataReader.Read()) 
       return dataReader; 
     } 
     catch (DbException) 
     { 
      // error executing command 
      connection.Close(); 
      return null; // or throw; // it depends on your logic 
     } 
    } 
    catch (DbException) 
    { 
     // if connection was not opened 
     return null; // or throw; // it depends on your logic 
    } 
    return null; 
} 
+0

Может быть, обернуть все в попытке поймать? –

+0

@DavidMerinos Да, это может быть вариант. Благодаря! – Tony

+0

Также вторая строка в этом, вероятно, избыточна: var command = connection.CreateCommand(); command.Connection = соединение; – Kakira