2012-11-18 3 views
0

아래의 코드를 살펴 제발있는 IEnumerator합니다 :VB.NET - 소개

'Form1.vb 
Imports System.Data.SqlClient 

Public Class Form1 

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     'ExecuteDataReader(Function(x) New Person With {.URN = x("URN")}) 
     Try 
      Dim results As IEnumerable(Of Person) = ExecuteDataReader(Function(x) New Person With {.URN = x("URN")}) 
      For Each c As Person In results 'Line 4 
      Next 
     Catch ex As Exception 

     Finally 

     End Try 

    End Sub 

    Public Function ExecuteDataReader(ByVal castRow As Func(Of IDataRecord, Person)) As IEnumerable(Of Person) 
     Try 
      Dim objCon As New SqlConnection("Data Source=IANSCOMPUTER;Initial Catalog=Test;Integrated Security=True") 
      Dim objCommand As New SqlCommand 
      Dim objDR As SqlDataReader 
      objCon.Open() 
      objCommand.Connection = objCon 
      objCommand.CommandText = "SELECT URN FROM Person" 
      objDR = objCommand.ExecuteReader() 
      Do While objDR.Read 
       castRow(objDR) 
      Loop 
     Catch ex As Exception 

     End Try 

    End Function 
End Class 

'Person.vb 
Public Class Person 
    'Implements IEnumerator, IEnumerable 
    Public URN As String 
End Class 

이유는 무엇 IEnumberators 새로운 오전 라인 4. 빈 변수 결과입니다. .NET 3.5 버전에서는 Yield 키워드를 사용할 수 없습니다.

업데이트 Damien_The_Unbeliever가이 코드를 수정했습니다. 이 패턴이 데이터 로직 레이어에 적합하다고 생각하십니까? 나는 4 가지 옵션이 있다고 믿는다 :

1) 데이터 리더 대신 비즈니스 로직 레이어로 데이터 테이블 반환. 그런 다음 using 문에서 코드를 래핑 할 수있게되었습니다.
2) Damien_The_Unbeliever의 대답에 설명 된 패턴을 사용하여 비즈니스 로직 계층으로 데이터 판독기를 반환합니다 (사용 문에서 일회용 객체를 래핑하지 않음).
3) 반환 데이터 판독기는 데이터 액세스 레이어하지 마십시오) 비즈니스 오브젝트 레이어를 과 DataReader를 즉 dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
4 닫힐 때에만 연결을 종료합니다. 비즈니스 로직 계층에서 필요시 연결을 열고 닫습니다. 나는 이것이 코드의 유지 보수성을 떨어 뜨린다 고 생각한다.

다른 옵션이있는 경우 알려 주시기 바랍니다.

+0

예외를 삼키지 마십시오. – SLaks

+0

함수가 아무 것도 반환하지 않습니다. – SLaks

+0

이 코드에 대한 컴파일러 경고가 표시됩니다. 그것을 무시하지 마십시오. –

답변

2

대신을 시도

가) 자동으로 오류를 삼킨 "오류 처리"의 나쁜 예를 제거
Public Function ExecuteDataReader(ByVal castRow As Func(Of IDataRecord, Person)) As IEnumerable(Of Person) 
    Using objCon As New SqlConnection("Data Source=IANSCOMPUTER;Initial Catalog=Test;Integrated Security=True") 
     Using objCommand as New SqlCommand("SELECT URN FROM Person",objCon) 
     Dim objDR As SqlDataReader 
     objCon.Open() 
     objDR = objCommand.ExecuteReader() 
     Dim ret as New List(Of Person) 
     Do While objDR.Read 
      ret.Add(castRow(objDR)) 
     Loop 
     Return ret 
     End Using 
    End Using 
End Function 

, B)가 제대로 배치받을 수 있도록 SqlCommandSqlConnection 객체를 랩, 및 c) 사실 함수에서 뭔가를 반환합니다.이 함수는 잘못된 위치에있었습니다.

+0

감사합니다. 이 솔루션을 사용하면 Person은 IEnumerable 또는 IEnumerator를 구현할 필요가 없습니다. List가 이러한 인터페이스를 구현하고 List를 반환하기 때문에 이럴 수 있습니까? – w0051977

+0

예,'List (Of T)'는'IEnumerable (Of T)'를 구현합니다. –

+0

코드 +1에 감사드립니다. 나는 그 질문을 갱신했다. 내 질문에 대한 업데이트를보고 가장 좋다고 생각하는 옵션을 알려주십시오. 나는 그 질문에 답을 표시 할 것이다. 다시 한번 감사드립니다. – w0051977