2008-09-13 3 views
48

이 방법을 효율적으로 사용할 수 있습니까?SqlCommand.Dispose가 연결을 닫습니까?

using(SqlCommand cmd = new SqlCommand("GetSomething", new SqlConnection(Config.ConnectionString)) 
{ 
    cmd.Connection.Open(); 
    // set up parameters and CommandType to StoredProcedure etc. etc. 
    cmd.ExecuteNonQuery(); 
} 

나의 관심사입니다 :합니다 (사용하여 블록을 종료 할 때 호출)을하는 SqlCommand의 폐기 방법은 기본 SqlConnection 개체를 닫거나하지 않을까요?

+0

SqlCommand com을 삭제 한 후에는 해당 Connection 인스턴스가 루트가 지정되지 않습니다 (아무것도 사용하지 않음). GarbageCollector가 SqlConnection 인스턴스를 마무리하면 연결이 삭제되지 않습니까? 내가 생각하기에 연결은 cmd 만 참조하기 때문입니다. – mecek

+0

그럴 경우 @Mecek, 메모리가 gen0에서 gen1로 승격되는 최종화를 거치므로 열심히 해방 될 것입니다. –

답변

97

아니요, SqlCommand을 처분해도 Connection에 영향을 미치지 않습니다. 더 나은 방법은 또한뿐만 아니라 사용하여 블록에서 SqlConnection를 포장하는 것 :

using (SqlConnection conn = new SqlConnection(connstring)) 
{ 
    conn.Open(); 
    using (SqlCommand cmd = new SqlCommand(cmdstring, conn)) 
    { 
     cmd.ExecuteNonQuery(); 
    } 
} 

그렇지 않으면, 연결은 사실에 의해 변경되지 않습니다 그 그것은 어쩌면 그게 당신이 원하는 것 (배치되었다 사용 된 명령?). 하지만 Connection은 도 처리해야하며 명령보다 처리하는 것이 더 중요 할 수 있습니다.

EDIT : 그냥이 테스트

다음 블록이 사용 종료 때

SqlConnection conn = new SqlConnection(connstring); 
conn.Open(); 

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 1", conn)) 
{ 
    Console.WriteLine(cmd.ExecuteScalar().ToString()); 
} 

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 2", conn)) 
{ 
    Console.WriteLine(cmd.ExecuteScalar().ToString()); 
} 

conn.Dispose(); 

첫 번째 명령을 배치 하였다. 연결은 여전히 ​​열려 있었고 두 번째 명령에 적합했습니다.

따라서 명령을 삭제해도 사용중인 연결은 확실히 삭제되지 않습니다.

+0

명령을 올바르게 작성하기 전에 연결을 열 필요가 없습니까? 확인 그것과 같은 작은 청소기 : 사용 (도록 SqlConnection CONN = 새도록 SqlConnection을 (connstring)) 사용 (하는 SqlCommand cmd를 = 새로운하는 SqlCommand (cmdstring 코네티컷 주)) { conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); } –

+0

나는 서식을 고수하지 않는다고 생각하지만 기본적으로 함께 문을 사용하여 중첩 수준을 제거합니다.(원하는 경우) –

+7

예제의 요점은 간단한 구문을 나타내지는 않지만 두 SqlCommands를 동일한 연결에서 사용할 수 있고 연결을 삭제하지 않고 처리 할 수 ​​있음을 보여주는 것입니다. 연결을 열어야하고이를 입증하기 위해 두 번 사용해야합니다 (원래 질문 참조). –

10

많은 SqlCommand가 동일한 SqlConnection을 (다시) 사용할 수 있기 때문에 SqlCommand.Dispose가 충분하지 않습니다. SqlConnection에 집중하십시오.

-10

이 패턴을 사용합니다. 나는 내 응용 프로그램 어딘가에이 개인 방법이 있습니다

private void DisposeCommand(SqlCommand cmd) 
{ 
    try 
    { 
     if (cmd != null) 
     { 
      if (cmd.Connection != null) 
      { 
       cmd.Connection.Close(); 
       cmd.Connection.Dispose(); 
      } 
      cmd.Dispose(); 
     } 
    } 
    catch { } //don't blow up 
} 

그럼 난 항상 try 블록에서 SQL 명령과 연결을 만들 (하지만 사용하여 블록에 싸여하지 않고)와 항상 마지막으로 차단했다 :

finally 
    { 
     DisposeCommand(cmd); 
    } 

명령 개체의 속성 인 연결 개체는이 상황에서 사용 블록을 어색하게 만듭니다. 그러나이 패턴은 코드를 어지럽히 지 않고 작업을 완료합니다.

+0

이것은 하나의 명령에 한 번만 연결을 사용한다고 가정하므로 새 명령을 실행할 때마다 새 연결을 만들어 열어야합니다. 연결을 만들고 여는 데 많은 오버 헤드가 있습니다. –

+8

내 눈에는 이것이보기 흉한 코드이며 명령을 자동 폐기하는'using' 문을 사용하는 것이 훨씬 깔끔할 것입니다. – KristianB

+2

다운 voting - 불필요하고 효과적이지 않은 'using'방법의 재 구현. – NickG

관련 문제