我正在使用System.Linq.Dynamic允许我从查询中动态选择字段列表,如下所示:
finalQuery = query.Select(string.Format("new({0})", string.Join(",", selectors)));
Run Code Online (Sandbox Code Playgroud)
其中selectors仅仅是一个List<string>与所有我想要的字段.这很好用,但这个版本的扩展方法Select返回一个IQueryable.不是这不是 IQueryable<T>.如果我有一个IQueryable<T>我可以简单地做一个.ToList()转换为列表并强制查询实际上在数据库上运行,但使用非泛型IQueryable,该方法不存在.
这是因为,ToList在继承了IEnumerable<T>其IQueryable<T>继承和IQueryable,显然,没有.
那么,获得IQueryable执行查询并给我一个列表的最有效方法是什么?我可以做这个:
List<object> rtn = new List<object>();
foreach (var o in finalQuery)
{
rtn.Add(o);
}
Run Code Online (Sandbox Code Playgroud)
但似乎他们应该是一个更容易的方式.
编辑:为了回应建议,我尝试了两个:
finalQuery.Cast<object>().ToList();
Run Code Online (Sandbox Code Playgroud)
和:
finalQuery.Cast<dynamic>().ToList();
Run Code Online (Sandbox Code Playgroud)
这两个都给出NotSupportedExceptions了消息:
Unable to cast the type 'DynamicClass1' to type 'System.Object'. LINQ to Entities
only supports casting EDM primitive or enumeration types.
Run Code Online (Sandbox Code Playgroud)
Tim*_* S. 18
这似乎是LINQ to Entities转换IQueryable.Cast为匿名类型的方式的限制.您可以通过将其用作IEnumerable(您的工作示例执行此操作)来解决此问题.这会导致代码在从数据库中检索后在.NET运行时执行转换,而不是尝试在数据库引擎中处理它.例如
IEnumerable finalQuery = query.Select(string.Format("new({0})",
string.Join(",", selectors)));
var result = finalQuery.Cast<dynamic>().ToList();
Run Code Online (Sandbox Code Playgroud)
要么
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>();
Run Code Online (Sandbox Code Playgroud)