2009-10-21 5 views
4

우리는 저장 프로 시저의 이름과 입력 매개 변수를 가져 와서 결과를 데이터 테이블로 반환하는 SQL 유틸리티 클래스를 가지고 있습니다. 이것의 뒤에있는 추론은 우리가 연결을 닫고 연결 누출을 잊는 것에 대해 걱정할 필요가 없기 때문입니다. 또한 데이터 액세스 레이어에서 데이터 어댑터 및 데이터 보관함을 다시 만들 필요가 없어 코드를 줄일 수 있습니다.유틸리티 클래스로 SQL 연결을 관리하는 방법은 무엇입니까?

내가 가진 문제점은 우리가 객체를 생성하기 위해 반복 할 수 있도록 데이터 테이블을 채우고 있다는 것입니다. 그래서 우리는 기본적으로 datareader처럼 사용하고 있습니다. datareader 또는 dataadapter를 반환하는 클래스에 대해 읽었습니다. 하지만이 문제는 클라이언트가 연결을 열고 닫아야하거나 Finalize 메서드로 연결을 닫아야한다는 것입니다. 가비지 콜렉션이 데이터베이스 연결을 종료하는 것을 원하지 않는 것 같습니다.

요약하면 모든 쿼리에 대해 데이터 배열을 만들지 않아도되므로 데이터베이스 연결이 닫힐 수 있도록 코드를 줄일 수있는 클래스가 필요합니다.

이 문제를 해결하는 가장 좋은 방법은 무엇입니까?

UPDATE : 아직도 이것에 대해 생각하지만, 지금까지가 가장 좋은 방법은 여전히 ​​DataReader를를 돌려 위해 CommandBehavior.CloseConnection를 사용하고 적() dr.Close를 호출하는 클래스를 사용하는 사람들 신뢰하는 것 같다?

답변

3

Microsoft Enterprise Library을 고려 했습니까?

public List<User> GetUsers() 
{ 
    List<User> result = new List<User>(); 

    Database db = new 
    Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase(this.connectionString); 
    DbCommand cmd = db.GetStoredProcCommand("GetUsers"); 

    using (IDataReader rdr = db.ExecuteReader(cmd)) 
    { 
     while (rdr.Read()) 
     { 
      User user = new User(); 
      FillUser(rdr, user);     
      result.Add(user); 
     } 
    } 
    return result; 

} 
+0

이 제안에 감사드립니다. 이것은 흥미로운 것 같습니다. –

1

동일한 구조 - 데이터를 가져 와서 채워진 DataTable (또는 전달 된 DataTable 채우기/업데이트) 메서드가있는 유틸리티 클래스 - 동일한 이유로 데이터베이스 연결을 다른 부분과 분리하여 유지합니다. 코드가 필요할 때만 열리고 가능한 빨리 닫히는 지 확인하십시오. 특히 데이터가 다양한 백엔드 시스템에 저장되어 있으므로 응용 프로그램에 하나의 인터페이스 만 표시하고 세부 사항은 걱정하지 않아야합니다.

상황에 따라 한 가지 다른 점이 있습니다. 우리는 (일반적으로) DataTable의 행에서 개체를 만들지 않고 행의 데이터에서 직접 작업합니다. DataTables로 간단하고 효율적으로 작업 할 수 있습니다.

이외에도 개인적으로이 접근법에 잘못된 점이 없으며 Google의 목적에 매우 적합하다는 것을 알았습니다.

2

우리는 이와 같은 것을 사용하며 높은 음량으로 매우 잘 수행합니다.

public SqlDataReader ExecuteReader(string command, SqlParameter[] parameters) 
    { 
     SqlDataReader reader = null; 

     using (SqlConnection conn = new SqlConnection()) 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
      conn.Open(); 

      cmd.CommandText = command; 
      cmd.CommandType = CommandType.StoredProcedure; 

      cmd.Parameters.AddRange(parameters); 

      reader = cmd.ExecuteReader(CommandBehavior.CloseConnection); 
     } 

     return reader; 
    } 

DataTables은 부풀어 오름과 유형 안전성 부족과 같은 여러 가지 이유로 우수 사례로 간주되지 않습니다.

+0

또한 데이터 판독기에서 개체를 채우는 데 관심이있는 경우 http://www.codeproject.com/KB/database/NullableReaders.aspx와 같은 것을 사용하는 것이 좋습니다. – Jason

+1

우리가 다루 려던 사항 중 하나는 연결을 닫는 것에 대해 걱정할 필요가 있습니다. 이것으로 당신은 수동으로 reader.Close를 호출하여 연결을 닫고 수정해야합니다. –

+0

@Chad Close는 using 문 끝에서 자동으로 발생하므로 실제로 코드에 추가 할 필요가 없습니다. 이 명령은 서버에서 발생하는 스레드 풀에서 사용자를 반드시 닫을 수는 없으므로 계속 명령을 보내면 서버의 스레드 풀에서 시간을 얻을 수 있습니다. 나는 또한 당신의 연결을 끊지 않는 것은 나쁜 생각이라고 언급해야한다고 생각합니다. – Jage

0

많은 경우에 datareader를 반환하는 것은 효과가 없습니다. 많은 곳에서, 클라이언트 시스템에서 데이터베이스로의 직접 연결은 프로덕션에서 허용되지 않습니다 (정당한 이유로). 따라서 검색하는 객체를 직렬화해야합니다. 나는 당신이 서버 측에서 원격/직렬화를 위해 사용하는 모든 클래스에서 datareader를 유지할 수 있다고 생각할 수 있지만 행 패션을 고민함으로써 행에있는 http 또는 nettcp를 통해 항목을 반환하는 것이 많은 이점을 제공하지는 않는다.

이 개체를 직렬화 하시겠습니까? 그렇다면 데이터 테이블, 데이터 집합 또는 사용자 지정 개체로 선택할 수 있습니다. 사용자 정의 객체는 잘 작성된 경우 최상의 성능을 내고 일련 번호를 지정하지만 일련의 다른 기능과 함께 동시성을 작성해야합니다.

IMO, ADO.Net 2.0부터 datatables는 대규모 원격 작업 환경에서도 성능이 뛰어납니다. 이들은 특별한 바이너리 원격 포맷을 제공하며 작업하기가 쉽습니다. 약간의 압축을 가하면 대용량 데이터 세트에 많은 대역폭을 사용하지 않습니다.

+0

기본 아이디어는 쿼리 결과를 반복하고 개체를 채울 수 있도록 datareader를 반환하는 것입니다. 그게 최선의 방법인지 확실하지 않습니다. 내 쇠고기는 지금 당장 데이터 테이블을 반환합니다. 그래서 우리는 객체를 생성하기 위해 행을 순환 할 수 있습니다 (본질적으로 데이터 배열로 사용). 나에게 맞는 것 같지 않아. –

0

웹 페이지에서이 클래스를 사용하려는 경우 페이지의 언로드 이벤트로 유틸리티 클래스를 등록 할 수 있습니다. 이벤트 싱크에서는 논리를 작성하여 데이터베이스 연결을 닫을 수 있습니다. Check out this tip on codeproject for more ideas.

그러나이 솔루션은 웹 메소드 (웹 서비스) 내에서 사용하기에 적합하지 않습니다. 웹 서비스 사용을 위해이 기술을 적용해야한다고 생각합니다. 웹 메소드의 마지막 행은 이벤트 호출이어야합니다. 따라서 웹 서비스 클래스를 작성할 때 WebMethodCompleted이라는 이벤트를 정의하십시오. 이 기사에서 언급 한 기술을 통해 웹 서비스 인스턴스에 대한 참조를 얻게 될 것입니다. 참조를 얻으면 유틸리티 클래스에 이벤트를 등록 할 수 있습니다. 웹 메서드에서 이벤트를 호출하는 것을 잊지 마십시오.

해피 프로그래밍.

관련 문제