Please have a look at the code below:
'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
Why is the results variable empty on line 4. I am new to IEnumberators. The version of .NET I am using (3.5) does not allow for the Yield keyword.
Update Damien_The_Unbeliever has corrected the code. Do you think this pattern is suitable for a Data Logic Layer. I believe I have four options:
1) Return Data Tables instead of Data Readers to the Business Logic
Layer. I am then able to wrap the code in Using statements.
2) Return Data Readers to the Business Logic Layer using the pattern
described in Damien_The_Unbeliever's answer (not wrapping the
disposable objects in Using statements).
3) Return Data Readers to
the Business Object Layer and only closing the connection when the
DataReader is closed i.e. dr =
cmd.ExecuteReader(CommandBehavior.CloseConnection)
4)Don't have a Data Access Layer. Open and close connections in the Business Logic
Layer as and when they are required. I believe this makes the code less maintainable.
If there is another option then please let me know.