How to convert List to runtime type (List>)

c# casting dapper dynamic-language-runtime linq

Question

I'm using a method that has a return signatur of IEnumerable<dynamic>. At runtime for a particular call it is returning List<Dapper.SqlMapper.FastExpando>.

var x0 = repo.Find(proc, param); 
//x0 runtime type is {List<Dapper.SqlMapper.FastExpando>}

LINQPad.Extensions.Dump indicates the runtime type of x0 is: List<IDictionary<String, Object>> but I can't seem to cast/convert to List<IDictionary<String, Object>>. Here is a screenshot of the Linqpad Dump: enter image description here

Ultimately I need to join all the Values from each Dictionary to a single IEnumerable<DateTime>.

IEnumerable<DateTime> GetDates(int productId) 
{
    const string proc = "[dbo].[myproc]";
    dynamic param = new { Id = "asdf" };
    var x0 = repo.Find(proc, param); 
    //...
    //linq conversion from x0 to IEnumerable<DateTime> here.
}

Error I'm getting

List<IDictionary<String, Object>> x5 = repo.Find(proc, param);

results in:

RuntimeBinderException: Cannot implicitly convert type 'object' to
 'System.Collections.Generic
     .List<System.Collections.Generic.IDictionary<string,object>>'.
An explicit conversion exists (are you missing a cast?)

BACKGROUND: I am using a Dapper wrapper and can't change the database table/stored procedure which returns denormalized results. Instead of 100 rows of 1 data element, the sproc returns 1 row of 100 columns. I wanted to avoid creating a class to represent the 100 columns and want to take advantage of Dapper's automagical ability to transpose the column data to rows via an IDictionary of columnName, columnValue.

UPDATE This appears to be an issue with the dynamic param. When specified inline, it works. If specified locally and then passes as a parameter, it fails.

IEnumerable<DateTime> GetDates(int productId) 
{
    const string proc = "[dbo].[myproc]";
    dynamic param = new { Id = "asdf" };

    //next line throws RuntimeBinderException: 'object' does not 
    //contain a definition for 'First'.
    //IDictionary<String, object> x0 = repo.Find(proc, param).First();

    //this succeeds:
    IDictionary<String, object> x0 = repo.Find(proc, new { Id = "asdf" }).First();

    IEnumerable<DateTime> qry2
       = x0.Values.AsQueryable()
           .Where(x => x != null)
           .Select(x => (DateTime) x);
    return qry2;
}

Here are the signatures for Find and Query:

//Repository::Find
public IEnumerable<dynamic> Find(string procName, object param = null)

//Dapper SqlMapper::Query
public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)

Popular Answer

You can use the LINQ Cast method to cast each item in the sequence.

List<IDictionary<String, Object>> data = repo.Find(proc, param)
    .AsEnumerable()
    .Cast<IDictionary<String, Object>>()
    .ToList();


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why