Database.Query返回类型应该是IEnumerable <dynamic> </dynamic>

时间:2013-03-29 19:55:10

标签: c# dynamic ienumerable webmatrix

大家好我需要帮助才能理解这件事。为什么在下面的代码中变量“ejes”和“habilidades”被解析为“动态”而第三个被解析为IEnumerable。这会影响下一个运行的代码,当我尝试调用扩展方法“Count()”时会出现异常,因为“ejes”和“habilidades”不是IEnumerable .....我根本就没有得到它。它们是“Database.Query”相同方法的结果。

以下是摘录:

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();

我放置了一个调试器的Image来显示变量的运行时类型。

Extrange return type

3 个答案:

答案 0 :(得分:2)

asignacion.id_nivelasignacion.id_asignatura是动态类型。

当您将动态类型作为参数传递给任何方法时,该方法的返回类型将变为动态,而不是MSDN所说的任何方式。您不能在动态类型上使用扩展方法。 Count()Enumerable上的扩展方法。这就是你得到例外的原因。

有两种方法可以解决问题并将返回类型还原为Enumerable。第一个是明确定义它:

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

另一种是将参数转换为非动态类型:

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

正如Knox指出的那样,你必须使用参数而不是string.Format。

答案 1 :(得分:0)

区别在于调试器是由于dificultades已经评估了 (var c_dif = dificultades.Count();)。
其他两个变量尚未评估(linq deferred)。 因此调试器了解更多有关dificultades的信息。

答案 2 :(得分:0)

你确定habilidades和另一个有数据吗?我认为可能是db.Query返回null,意味着没有返回任何行,然后habilidades.Count无法执行,因为null没有要执行的对象。在调试器外部测试它的一种方法是执行db.QueryValue(“从...中选择计数(*)”)并查看是否返回零行。

顺便说一下,C#中的数据库函数以比你稍微短一些的方式构建变量处理。你可以写

var ejes = db.Query( @"
        Select *  
        From asign  
        Where id_nivel = @0",   
        asignacion.id_nivel );  

此技术称为参数化SQL。我只显示一个参数,但您需要更多参数。 @ 0,@ 1,@ 2等等就像在String.Format中一样被替换。