t-sqldapperresultset

How to mitigate "No columns were selected" exception from GridReader


I am getting this exception from Dapper.SqlMapper.GridReader when calling

var resultSet = await SqlConnection.QueryMultipleAsync(query, parameters, commandType: CommandType.StoredProcedure);
var results = await resultSet.ReadAsync<resultDb>();

No columns were selected at Dapper.SqlMapper.GetTypeDeserializerImpl(Type type, DbDataReader reader, Int32 startBound, Int32 length, Boolean returnNullIfFirstMissing) in /_/Dapper/SqlMapper.cs:line 3291 etc.*

This is a natural result of no rows being available in the GridReader, but I would like to mitigate this case in my code without exception handling.

unfortunately GridReader.IsConsumed is yielding false in my case (maybe due to an OUTPUT parameter?), so I can't use this as a switch.

I'm looking for some way to access the GridReader.Reader.HasRows without reflection as it yields the correct false for my scenario, but I can't seem to find it exposed anywhere.

What would be the way to do this? (I am not looking for a "return dummy rows" answer)


Solution

  • This exception isn't thrown because there is no rows in the GridReader.

    This exception is thrown because there is no columns in the GridReader.

    For example the procedure like this will make this exception to happen:

    CREATE PROCEDURE Test AS
    BEGIN
        IF 1=0
            RETURN;
    
        SELECT * FROM test_table;
    END
    

    To prevent this exception from happening do not return from procedure without returning at least empty set. For example like this:

    CREATE PROCEDURE Test AS
    BEGIN
        IF 1=0
        BEGIN
            -- returning empty set with a schema
            SELECT TOP 0 * FROM test_table;
            RETURN;
        END
    
        SELECT * FROM test_table;
    END
    

    AFIK unfortunately Dapper currently doesn't have a count of the available result sets in the GridReader. That information could be very useful here.