Search code examples
c#dynamicienumerablewebmatrix

Database.Query return type should be IEnumerable<dynamic>


I need help to understand this thing. Why in the following code the variables "ejes" and "habilidades" are resolved as "dynamic" and the third as IEnumerable<dynamic>. This is affecting the code that runs next, an exception appears when I try to invoke the extension method "Count()" because "ejes" and "habilidades" are not IEnumerable. They are the result of the same method "Database.Query".

Here is the snippet:

var db = Database.Open("froned");
db.Execute("begin transaction");

try
{
  var asignacion = db.QuerySingle("select * from asignacion_avanza where id_asignacion = @0", id_asignacion);

  var ejes = db.Query(String.Format(@"
                                  select id_eje
                                    from asignatura_eje_nivel
                                   where id_nivel = {0}
                                     and id_asignatura = {1}",
                                       asignacion.id_nivel,
                                       asignacion.id_asignatura));

  var habilidades = db.Query(String.Format(@"
                                  select id_habilidad
                                    from asignatura_habilidad_nivel
                                   where id_nivel = {0}
                                     and id_asignatura = {1}",
                                       asignacion.id_nivel,
                                       asignacion.id_asignatura));
  var dificultades = db.Query("select id_dificultad from dificultad");

  var c_dif = dificultades.Count();
  var c_eje = ejes.Count();
  var c_habilidades = habilidades.Count();

I put an Image of the debugger to show the runtime type of the variables.

Extrange return type


Solution

  • asignacion.id_nivel and asignacion.id_asignatura are dynamic types.

    When you pass a dynamic type into any method as an argument, the return type of the method becomes dynamic instead of whatever MSDN says it is. You cannot use extension methods on dynamic types. Count() is an extension method on Enumerable. That's why you get the exception.

    There are two ways to solve the problem and revert the return type to Enumerable. The first is to define it explicitly:

    IEnumerable<dynamic> data = db.Query(someSQL, parameterValue);
    

    and the other is to cast the parameter to a non-dynamic type:

    var data = db.Query(someSQL, (string)parameterValue);
    

    And as Knox points out, you must use parameters rather than string.Format.