Search code examples
dapper

Dapper Results(Dapper Row) with Bracket Notation


According to the Dapper documentation, you can get a dynamic list back from dapper using below code :

var rows = connection.Query("select 1 A, 2 B union all select 3, 4");

((int)rows[0].A)
   .IsEqualTo(1);

((int)rows[0].B)
   .IsEqualTo(2);

((int)rows[1].A)
   .IsEqualTo(3);

((int)rows[1].B)
    .IsEqualTo(4);

What is however the use of dynamic if you have to know the field names and datatypes of the fields. If I have :

var result = Db.Query("Select * from Data.Tables");

I want to be able to do the following : Get a list of the field names and data types returned.

Iterate over it using the field names and get back data in the following ways :

result.Fields
["Id", "Description"]

result[0].values
[1, "This is the description"]

This would allow me to get

result[0].["Id"].Value

which will give results 1 and be of type e.g. Int 32

result[0].["Id"].Type --- what datattype is the value returned

result[0].["Description"]

which will give results "This is the description" and will be of type string.

I see there is a results[0].table which has a dapperrow object with an array of the fieldnames and there is also a result.values which is an object[2] with the values in it, but it can not be accessed. If I add a watch to the drilled down column name, I can get the id. The automatically created watch is :

(new System.Collections.Generic.Mscorlib_CollectionDebugView<Dapper.SqlMapper.DapperRow>(result as System.Collections.Generic.List<Dapper.SqlMapper.DapperRow>)).Items[0].table.FieldNames[0]   "Id"    string

So I should be able to get result[0].Items[0].table.FieldNames[0] and get "Id" back.


Solution

  • You can cast each row to an IDictionary<string, object>, which should provide access to the names and the values. We don't explicitly track the types currently - we simply don't have a need to. If that isn't enough, consider using the dapper method that returns an IDataReader - this will provide access to the raw data, while still allowing convenient call / parameterization syntax.

    For example:

    var rows = ...
    foreach(IDictionary<string, object> row in rows) {
        Console.WriteLine("row:");
        foreach(var pair in row) {
            Console.WriteLine("  {0} = {1}", pair.Key, pair.Value);
        }
    }