0

以下のコードをご覧ください。

'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

4 行目の結果変数が空なのはなぜですか。私は IEnumberators を初めて使用します。私が使用している .NET のバージョン (3.5) では、Yield キーワードを使用できません。

更新 Damien_The_Unbeliever がコードを修正しました。このパターンはデータ ロジック層に適していると思いますか。次の 4 つのオプションがあると思います。

1) データ リーダーの代わりにデータ テーブルをビジネス ロジック層に返します。その後、Using ステートメントでコードをラップできます。
2) Damien_The_Unbeliever の回答で説明されているパターンを使用して、データ リーダーをビジネス ロジック レイヤーに返します (Using ステートメントで使い捨てオブジェクトをラップしません)。
3) データ リーダーをビジネス オブジェクト層に戻し、DataReader が閉じられている場合にのみ接続を閉じます。つまり、dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
4) データ アクセス層がありません。必要に応じて、ビジネス ロジック層で接続を開いたり閉じたりします。これにより、コードの保守性が低下すると思います。

別のオプションがある場合は、お知らせください。

4

1 に答える 1

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

a)エラーを黙って飲み込む「エラー処理」の悪い例を削除し、b)適切に破棄されるようにSqlCommandandSqlConnectionオブジェクトをラップし、c)関数から実際に何かを返しますが、これは間違っていた場所です。

于 2012-11-18T13:41:01.620 に答える