Harugawa Harugawa - 14 days ago 11
C# Question

Casting IEnumerable<dynamic> with custom class

I've been using dapper lately and wanted to make a dynamic method that would make it easier to select things out with sql.
This is my code:

Class:

public class Method
{
public static IEnumerable<dynamic> QueryAll(string table)
{
dynamic dyn = table;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DbCon"].ToString());
using (con)
{
string sql = String.Format("SELECT * FROM {0}", table);
IEnumerable<dynamic> ie = con.Query<dynamic>(sql, null);
return ie;
}

}
}


Calling function here:

IEnumerable<posts> = Method.QueryAll("posts");


It gives me an error
that I cannot convert IEnumerable dynamic to IEnumerable Models.Posts
.

How can I cast it to make it work.

Answer

Technically you could just use the IEnumerable.Cast-method to cast every instance returned from the method to the actual instance.

IEnumerable<posts> = Method.QueryAll("posts").Cast<posts>();

However if you allready know the the actual type why not use it in the query allready? dynamic should be handled with care and only if your really have to, which I doubt is the case here. You could for example add the actual type as type-parameter to the method:

public static IEnumerable<T> QueryAll<T>(string table)
{ 
    SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DbCon"].ToString());
    using (con)
    {
        string sql = String.Format("SELECT * FROM {0}", table);
        IEnumerable<T> ie = con.Query<T>(sql, null);
        return ie;
    }
}

Now you can call it as follows:

var result = Method.QueryAll<posts>("posts");

As an aside Method is a really bad class-name, as posts also. You should give your class names that describe what they serve for and what they are doing. Moreover there are naming-conventions suggesting to use PascalCase-names for class making your class Posts. At last when you have an enumeration of posts, I suppose the class itself represents one single post, not many, so you actual want a class named Post which you can store into an IEnumerable<Post>.