Search code examples
c#async-awaitdbdatareader

using GetFieldValueAsync with type from GetFieldType


I have a generic reader and I want to transform it from sync to async.

The original code is

while (DR.Read())
{
    count++;
    Field[] fields = new Field[DR.FieldCount];
    for (int i = 0; i < DR.FieldCount; i++)
    {
        Field field = new Field();
        field.RowCount = count;
        field.FieldCount = i;
        field.Name = DR.GetName(i);
        field.DataType = DR.GetDataTypeName(i);
        // decimal overflow workaround 
        field.ObjValue =
            field.DataType == "Decimal"?
            DR.GetDouble(i) :
            DR.GetValue(i);
        fields[i] = field;
    }
    yield return fields;
}

and it is ok. What I have tried to do is

List<Field[]> ret = new List<Field[]>();
while (await DR.ReadAsync())
{
    count++;
    Field[] fields = new Field[DR.FieldCount];
    for (int i = 0; i < DR.FieldCount; i++)
    {
        Field field = new Field();
        field.RowCount = count;
        field.FieldCount = i;
        field.Name = DR.GetName(i);
        field.DataType = DR.GetDataTypeName(i);
        // decimal overflow workaround 
        field.ObjValue =
            field.DataType == "Decimal" ?
            ((object)await DR.GetFieldValueAsync<double>(i)) :
            ((object)await DR.GetFieldValueAsync(i));
        fields[i] = field;
    }
    ret.Add(fields);
}

which is not working because of error CS0411

The type arguments for method 'GetFieldValueAsync' cannot be inferred from the usage. Try specifying the type arguments explicitly.

I have also tried to specify the type from Type t = DR.GetFieldType(i) but I can't do await DR.GetFieldValueAsync<t>(i) either.

Am I out of luck here?

Should I revert to the following blocking code inside my async method?

// decimal overflow workaround 
field.ObjValue =
    field.DataType == "Decimal" ?
    DR.GetDouble(i) :
    DR.GetValue(i);

Is there a theoretical reason why there is no DR.GetValueAsync(i) returning an object like the sync counterpart??

Minor note, out of topic

In case someone insists to know why I'm writing a different code for decimal, this is the issue.


Solution

  • I asssume you're talking about the DbDataReader Class.

    From the documentation:

    Reads a forward-only stream of rows from a data source.

    Once the row is read by either Read or ReadAsync, the values for that row will all be in memory, which doesn't require any I/O and, thus, doesn't need to be asynchronous.

    Update:

    Turns out, there's a GetFieldValueAsync method in the DbDataReader Class, but not a GetValueAsync method.