可以列出的IQueryable

时间:2014-08-22 18:14:25

标签: c# linq

我正在使用System.Linq.Dynamic来允许我从查询中动态选择字段列表,如下所示:

finalQuery = query.Select(string.Format("new({0})", string.Join(",", selectors)));

selectors只是List<string>,其中包含我想要的所有字段。这很有用,但此版本的扩展方法Select会返回IQueryable。这不是 IQueryable<T>。如果我有一个IQueryable<T>我可以简单地执行.ToList()将其转换为列表并强制查询实际在数据库上运行,但使用非泛型IQueryable,该方法不存在。

这是因为ToList继承自IEnumerable<T>IQueryable<T>继承而IQueryable,显然不会。{/ p>

那么,让IQueryable执行查询并给我一个列表的最有效方法是什么?我可以这样做:

List<object> rtn = new List<object>();
foreach (var o in finalQuery)
{
    rtn.Add(o);
}

但似乎他们应该是一种更容易的方式。

编辑:为了回应建议,我尝试了两个:

finalQuery.Cast<object>().ToList();

finalQuery.Cast<dynamic>().ToList();

两者都给NotSupportedExceptions留言:

Unable to cast the type 'DynamicClass1' to type 'System.Object'. LINQ to Entities 
only supports casting EDM primitive or enumeration types.

1 个答案:

答案 0 :(得分:18)

这似乎是LINQ to Entities使用匿名类型转换IQueryable.Cast的方式的限制。您可以将其用作IEnumerable(您的工作示例执行此操作)来解决此问题。这会导致代码在从.NET运行时中执行强制转换,而不是尝试在数据库引擎中处理它。 E.g。

IEnumerable finalQuery = query.Select(string.Format("new({0})",
                                                   string.Join(",", selectors)));
var result = finalQuery.Cast<dynamic>().ToList();

或者

public static IList<T> CastToList<T>(this IEnumerable source)
{
    return new List<T>(source.Cast<T>());
}

var finalQuery = query.Select(string.Format("new({0})",
                                            string.Join(",", selectors)));
var result = finalQuery.CastToList<dynamic>();