我正在使用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.
答案 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>();