2009-11-06 5 views
1

.Net에 대한 내 경험이 회사의 기존 사내 응용 프로그램에서 실제로 시작됨에 따라이를 깨닫지 못한 채 여러 가지 코딩 방법을 익혔습니다. 필자가 필사적으로 시도한 것은 DataSet이 모든 것에 사용된다는 것입니다. (나는 강력하게 형식화 된 데이터 세트가 있고 그 중 일부는 분명히 사용되지만 데이터를 선택하는 것과 같은 대다수의 경우는 제외)일반 DataReader 코드 (.net)의 예

일반 데이터베이스 작업을위한 "헬퍼"클래스를 구축하고 있습니다. .. 데이터 테이블 (선택 등) 반환하는 메서드가 있어요 및 기본적으로 (및 도서/온라인 대부분의 예제) DataAdapter의 채우기 메서드를 사용하지만 확실히 성능 게인,이 바꾸고 싶습니다 모든 행을 읽은 다음 닫는 데이터 판독기로 ... 필자가 Fill 메서드가 어떻게 작동하는지 알 것입니다. 그러나 큰 결과 집합의 성능이 잠재적으로 발생할 경우 게으른 방식으로 진행하지 않는 것이 좋습니다. 충격을 위해.

어쨌든, 필자는 내 인생에서 데이터 테이블을 일반적으로 채우는 데 사용되는 dataReader의 예를 발견 할 수 없다. 좋은 예제와 나쁜 예제가 모두있을 것이므로 동의 한 모범 사례는 다음과 같다. 그런 작업을 수행하는 방법. 이러한 코드에 대한 링크 (또는 심지어 게시물)는 훌륭합니다! 나는 주로 VB.Net이지만 C#은 장애물이 아닙니다.

참고 : 유감스럽게도이 게으른 소리가 들리면 전례없이 이런 종류의 예제가 게시 될 것이라고 생각했습니다. 바퀴 등을 다시 고칠 필요가 없습니다. 감사합니다! 그냥 바퀴를 개혁 할 것이다, 그래서 당신이 DataReader의 예를 찾을 수 없습니다

+1

시도하고 테스트 한 DataAdapter 사용. 특정 요구 사항이없는 조기 낙천주의는 나쁜 습관의 한 예입니다. – sipwiz

+0

요구 사항이 충족되기 전에 최적화에 관한 우수한 점이 있습니다. 그러나 DataReader를 사용하여 (내가 읽은 것부터) 입증 된 성능 향상 (특히 행이 늘어남에 따라)이 발생했을 때 행 수가 늘어날 때 선택할 수있는 일반적인 방법을 제공하는 것이 필수적이라고 생각합니다. 큰 것으로 예상된다. – davidsleeps

답변

3

이유는, 일반적으로 당신이 DataSetFill() 방법과 같은 일을 할 수 있기 때문에 DataTable가 채우는 데 사용된다.

DataTable을 DataReader로 직접 채우면 성능 이점을 얻지 못할 것입니다.

1

필자가 추측해야 할 점은, sqldataadapter를 Fill() 메서드와 비교할 때 sqldatareader를 사용하여 datatable을 채우는 것의 성능상의 이점은 없을 것이라고 생각합니다.

실제로 이론을 검증하는 유일한 방법은 직접 구현을 작성하고 비교하는 것입니다. 그러나 Fill()이 실행중인 코드를보고 정확히 무엇을하는지 확인할 수도 있습니다. 코드를 살펴 보려면 Reflector을 다운로드하는 것이 좋습니다.

나는 이것을 직접했다. 전화를 한 후에 다음) (채우기 결국 소위의 :이 모든보고 후

Friend Function FillFromReader(ByVal dataset As DataSet, ByVal datatable As DataTable, ByVal srcTable As String, ByVal dataReader As DataReaderContainer, ByVal startRecord As Integer, ByVal maxRecords As Integer, ByVal parentChapterColumn As DataColumn, ByVal parentChapterValue As Object) As Integer 
    Dim num2 As Integer = 0 
    Dim schemaCount As Integer = 0 
    Do 
     If (0 < dataReader.FieldCount) Then 
      Dim mapping As SchemaMapping = Me.FillMapping(dataset, datatable, srcTable, dataReader, schemaCount, parentChapterColumn, parentChapterValue) 
      schemaCount += 1 
      If (((Not mapping Is Nothing) AndAlso (Not mapping.DataValues Is Nothing)) AndAlso (Not mapping.DataTable Is Nothing)) Then 
       mapping.DataTable.BeginLoadData 
       Try 
        If ((1 = schemaCount) AndAlso ((0 < startRecord) OrElse (0 < maxRecords))) Then 
         num2 = Me.FillLoadDataRowChunk(mapping, startRecord, maxRecords) 
        Else 
         Dim num3 As Integer = Me.FillLoadDataRow(mapping) 
         If (1 = schemaCount) Then 
          num2 = num3 
         End If 
        End If 
       Finally 
        mapping.DataTable.EndLoadData 
       End Try 
       If (Not datatable Is Nothing) Then 
        Return num2 
       End If 
      End If 
     End If 
    Loop While Me.FillNextResult(dataReader) 
    Return num2 
End Function 

:

Protected Overridable Function Fill(ByVal dataTables As DataTable(), ByVal dataReader As IDataReader, ByVal startRecord As Integer, ByVal maxRecords As Integer) As Integer 
    Dim num3 As Integer 
    Dim ptr As IntPtr 
    Bid.ScopeEnter(ptr, "<comm.DataAdapter.Fill|API> %d#, dataTables[], dataReader, startRecord, maxRecords" & ChrW(10), Me.ObjectID) 
    Try 
     ADP.CheckArgumentLength(dataTables, "tables") 
     If (((dataTables Is Nothing) OrElse (dataTables.Length = 0)) OrElse (dataTables(0) Is Nothing)) Then 
      Throw ADP.FillRequires("dataTable") 
     End If 
     If (dataReader Is Nothing) Then 
      Throw ADP.FillRequires("dataReader") 
     End If 
     If ((1 < dataTables.Length) AndAlso ((startRecord <> 0) OrElse (maxRecords <> 0))) Then 
      Throw ADP.NotSupported 
     End If 
     Dim num2 As Integer = 0 
     Dim enforceConstraints As Boolean = False 
     Dim dataSet As DataSet = dataTables(0).DataSet 
     Try 
      If (Not dataSet Is Nothing) Then 
       enforceConstraints = dataSet.EnforceConstraints 
       dataSet.EnforceConstraints = False 
      End If 
      Dim i As Integer 
      For i = 0 To dataTables.Length - 1 
       If dataReader.IsClosed Then 
        goto Label_00DE 
       End If 
       Dim container As DataReaderContainer = DataReaderContainer.Create(dataReader, Me.ReturnProviderSpecificTypes) 
       If (container.FieldCount > 0) Then 
        If ((0 < i) AndAlso Not Me.FillNextResult(container)) Then 
         goto Label_00DE 
        End If 
        Dim num4 As Integer = Me.FillFromReader(Nothing, dataTables(i), Nothing, container, startRecord, maxRecords, Nothing, Nothing) 
        If (i = 0) Then 
         num2 = num4 
        End If 
       End If 
      Next i 
     Catch exception1 As ConstraintException 
      enforceConstraints = False 
      Throw 
     Finally 
      If enforceConstraints Then 
       dataSet.EnforceConstraints = True 
      End If 
     End Try 
    Label_00DE: 
     num3 = num2 
    Finally 
     Bid.ScopeLeave((ptr)) 
    End Try 
    Return num3 
End Function 

이 다음 FillFromReader()를 호출합니다 것을 알 수 있습니다 나는 내 마음을 바꿔야 할 수도 있습니다. 이 모든 것을 위해 직접 구현을 작성하는 데 실제로 상당한 개선이있을 수 있습니다. 필자는 FillNextResult()를 계속 호출 할 때 함수 호출의 오버 헤드뿐만 아니라 예상보다 많은 로직이 있습니다.

+0

그 코드를 드래그 해 주셔서 고마워요, 몇 가지 질문이 생깁니다 ...하지만 아래에있는 datareader를 사용할 때 그럴 가치가 없을 것입니다 ... – davidsleeps

0

다음은 datatable을 일반적으로 채우는 데 사용되는 dataReader의 예입니다. 당신은 단순히 DataTable에의로드 방법을 사용하고 그것을 DataReader를 전달할 수 있습니다 : DataReader를을 사용하지만, 지금까지 성능이가는대로 당신은 당신이 더 튀어 나와있을 거라고 demonstratable 문제를 찾을 수 있습니다하지 않는 방법을 배우는 전혀 해가 없다

DataTable dt= new DataTable(); 
dt.Load(cmd.ExecuteReader()); //cmd being declared as SqlCommand