2009-06-03 1 views
0

에서 DB에 호출 후 종료되지 않는다 닫히지 마라. 처음으로 페이지를 요청할 때 데이터를 잘 볼 수 있습니다. 다시로드에 나는 다음과 같은 오류 얻을 : 마지막으로연결 내가 ASP.NET에서 저장 프로 시저를 호출하는 일반적인 방법이 ASP.NET

The connection was not closed. The connection's current state is open. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: The connection was not closed. The connection's current state is open.

Source Error:

Line 35: Line 36: } Line 37: sql.Connection.Open(); Line 38: iReader = sql.ExecuteReader(CommandBehavior.CloseConnection); Line 39: sql.Dispose();

를 내가) sql.Connection.Close를 (넣어 경우; before sql.Dispose(); 이미 닫혀 있기 때문에 iReader를 읽을 수 없다는 오류가 나타납니다.

분명히 연결을 잘못 닫고 있습니다. 누군가 올바른 방향으로 나를 가리킬 수 있습니까?

답변

4

, 기본 연결이 열린 상태를 유지해야합니다. 자원을 적절하게 정리하는 것은 소비자의 책임입니다.

public SqlDataReader ExecuteStoredProc(string sprocName, SqlParameter[] SqlP) 
{ 
    SqlCommand sql = new SqlCommand(); 

    sql.CommandText = sprocName; 
    sql.CommandType = CommandType.StoredProcedure; 
    sql.Connection = ConnStr; 
    if (SqlP != null) 
    { 
     foreach (SqlParameter p in SqlP) 
     { 
      sql.Parameters.Add(p); 
     } 

    } 
    sql.Connection.Open(); 
    return sql.ExecuteReader(CommandBehavior.CloseConnection);   
} 

public void ConsumingMethod() 
{ 
    using(SqlDataReader reader = ExecuteStoredProc("MyProc", params)) 
    { 
     while(reader.Read()) 
     { 
      //work with your reader 
     } 
    } 
} 
+0

나는 "자원을 적절하게 정리하는 소비자의 책임"이라는 귀하의 접근 방식에 동의하지만, 일반적으로 이에 의존하지 않으므로 소비자는이 작업을하기에는 너무 게으른 것입니다. –

+0

감사합니다. 내 while 루프 다음에 내 consumingmethod에 iReader.Close()를 추가했습니다. – RedWolves

+0

ExecuteStoredProc에서 생성하는 연결을 닫고 처리 할 필요가 없습니까? –

1

"using"문과 함께 SQL 연결을 감싸는 것이 좋습니다. 그러면 대부분의 SQL 연결 문제가 해결됩니다. 당신이 DataReader가를 반환하면

using (var conn = new SqlConnection("...")) 
{ 
    conn.Open(); 
    using (var cmd = conn.CreateCommand()) 
    { 
     cmd.CommandText = "..."; 
     using (var reader = cmd.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       // ... 
      } 
     } 
    } 

}

+0

또한 SqlDataReader를 반환하지 않으므로 사용자 지정 개체를 초기화 한 다음 개체를 반환하는 것이 가장 좋습니다. –

0

아이디어는 Connection.Close()를 수행하는 것입니다. SqlReader를 끝내면 기본적으로 SqlReader.Dispose() 명령 앞에 close() 문을 배치하는 대신 아래에 배치해야합니다.

0

IDataReader를 처리하기 위해 내가 선호하는 방법입니다. 호출자가 SqlConnection 인스턴스를 만들고 메서드에 전달하도록합니다.

SqlConnection 인스턴스를 만드는 데 비용이 많이 듭니다. 그리고 다른 상황에서 동일한 ExecuteStoredProc 메서드를 여러 번 호출하게됩니다.

따라서 매개 변수의 일부로 SqlConnection 인스턴스를 추가하여 ExecuteStoredProc 메서드를 리팩터링합니다.

using (SqlConnection conn = new SqlConnection()) 
{ 
    conn.ConnectionString = // Connection String; 
    conn.Open(); 

    using (IDataReader reader = foo.ExecuteStoredProc(conn, sprocName, SqlP)) 
    { 
     // Process IDataReader 
    } 
}