0

I need to know how to convert the following to VB.net for an Async/Await project:

public static class Extensions {

    public static IEnumerable<T> Select<T>(
        this SqlDataReader reader, Func<SqlDataReader, T> projection) {

        while (reader.Read()) {
            yield return projection(reader);
        }
    }
}

Usage:

'call the database asynchronously... and 'await' the results
Using reader = Await Db.GetReaderAsync("spGetDashboard", ParamList)
    Return reader.Select(Function(r)
                             Return New DashboardInfo With {.RowNum = CType(r.Item("RowNum"), Long?)}
                         End Function)

Here is what I have so far:

<Extension()>
Public Function [Select](Of T)(reader As SqlDataReader, projection As Func(Of SqlDataReader, T)) As IEnumerable(Of T)
    While reader.Read()
        Return CType(projection(reader), IEnumerable(Of T))
    End While
End Function

Here is the exception:

System.InvalidCastException: Unable to cast object of type 'WindowsApplication1.DashboardInfo' to type 'System.Collections.Generic.IEnumerable`1[WindowsApplication1.DashboardInfo]'. at WindowsApplication1.Extensions.Select[T](SqlDataReader reader, Func`2 projection) in C:\Dev\AsyncDbTesting\AsyncDbTesting\Library\Extensions.vb:line 523
at WindowsApplication1.Process.VB$StateMachine_1_GetDashboardAsync.MoveNext() in C:\Dev\AsyncDbTesting\AsyncDbTesting\Process.vb:line 30 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at WindowsApplication1.Form1.VB$StateMachine_0_Button1_Click.MoveNext() in C:\Dev\AsyncDbTesting\AsyncDbTesting\Form1.vb:line 17

svick
  • 236,525
  • 50
  • 385
  • 514
Bryan
  • 112
  • 1
  • 11

1 Answers1

0

The exception is being thrown because you're trying to convert an item of type T into type IEnumerable(Of T).

Assuming you're using .Net framework 4.5, the code you want is

<Extension()>
Public Iterator Function [Select](Of T)(reader As SqlDataReader, projection As Func(Of SqlDataReader, T)) As IEnumerable(Of T)
    While reader.Read()
        Yield projection(reader)
    End While
End Function

Note that Yield and the concept of iterators don't exist in VB.NET before .Net framework 4.5.

prprcupofcoffee
  • 2,950
  • 16
  • 20