VB.NET-IEnumerator简介

VB.NET-IEnumerator简介,vb.net,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")}) Tr

请查看以下代码:

'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行的results变量为空。我是个新手。我使用的.NET版本(3.5)不允许使用Yield关键字

更新 Damien_不信者已经更正了密码。您认为这种模式适合于数据逻辑层吗。我相信我有四个选择:

1) 将数据表而不是数据读取器返回到业务逻辑 层。然后,我可以使用语句将代码包装起来。
2) 使用模式将数据读取器返回到业务逻辑层 在Damien_不信者的回答中描述(不包装 使用语句中的一次性对象)。
3) 将数据读取器返回到 业务对象层,并且仅在 数据读取器已关闭,即
dr=
cmd.ExecuteReader(CommandBehavior.CloseConnection)

4) 没有数据访问层。在业务逻辑中打开和关闭连接 根据需要分层。我相信这会降低代码的可维护性

如果还有其他选择,请告诉我。

试试以下方法:

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)包装
SqlCommand
SqlConnection
对象,以便它们得到正确的处理;c)实际从函数返回一些内容,这正是您出错的地方。

您的函数不返回任何内容。您应该为此代码收到编译器警告。不要忽视它。@SLaks,谢谢。我试图在回答我在这里写的前一个问题时修改代码:你不会对卡斯特罗的结果做任何事情,
castRow
。@Damien\u不信者,谢谢。我正在尝试将此问题的公认答案中的代码改编为.NET3.5。您能告诉我如何用Persons填充Results变量吗?谢谢。使用此解决方案,Person不必实现IEnumerable或IEnumerator。这是因为List实现了这些接口,而您正在返回一个List吗?是的,
List(Of T)
implements
IEnumerable(Of T)
。感谢+1的代码。我已经更新了问题。你能看一下我问题的更新,让我知道你认为什么是最好的选择吗?然后我将标记所回答的问题。再次感谢。@w0051977-re:您的更新-除非您喜欢编写大量重复的代码(仍然很容易出错、泄漏原始版本中的连接等),否则我建议您查看ORM(或微型ORM),不要自己编写任何DB代码,谢谢。你最后的评论是我的长期计划。我的短期计划将是我更新中的选项之一。你认为哪一个最合适?