使用“提供的参数”在 Queryable 上找不到 OrderBy。
我有一个想要用来对列表进行排序的方法:
private static IQueryable<T> BuildQuery<T>(IQueryable<T> query,
string methodName,
Expression<Func<T, object>> property)
{
var typeArgs = new[] { query.ElementType, property.Body.Type };
methodCall = Expression.Call(typeof (Queryable),
methodName,
typeArgs,
query.Expression,
property);
return query.Provider.CreateQuery<T>(methodCall);
}
当我使用以下参数执行代码时出现异常:
var myPreExistingQuery = new List<SomeType>{ new SomeType() }.AsQueryable();
var query = BuildQuery(myPreExistingQuery, "OrderBy", x => x.SomeProperty);
异常是:
No method 'OrderBy' on type 'System.Linq.Queryable' is compatible with the supplied arguments.
任何人都可以看到我在这里缺少的内容吗?
编辑:
我尝试了另一个重载 Expression.Call() 并得到了相同的异常:
private static IQueryable<T> BuildQuery<T>(IQueryable<T> query, string methodName, Expression<Func<T, object>> propertyExpression)
{
var methodCall = Expression.Call(query.Expression,
methodName,
new[] {query.ElementType, property.Body.Type},
new[] {propertyExpression});
return query.Provider.CreateQuery<T>(methodCall);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于您希望属性选择器表达式动态地进行适当的调用,因此您必须为其创建一个新表达式。您无法按原样使用提供的选择器,因为它当前输入的是
Expression>
并且不返回您的特定类型Expression>
。您也许可以通过更改接受object
调用的类型参数来编译它,但它不会按预期工作,因为它将进行对象引用比较(并且您的 LINQ 提供程序可能会拒绝无论如何)。要重新创建选择器表达式,您可以这样做:
这样做的一个不错的替代方法是使属性类型也通用。这样,您从一开始就会得到一个适当的强类型选择器。
Since you want your property selector expression to make the appropriate calls dynamically, you must create a new expression for it. You cannot use the provided selector as-is since it is currently typed
Expression<Func<T, object>>
and not returning your specific typeExpression<Func<T, SomeType>>
. You might be able to get it to compile by changing the type arguments of the call to acceptobject
but it will not work as expected since it will be doing object reference comparisons (and your LINQ provider will may reject it anyway).To recreate your selector expression, you could do this:
A nice alternative to doing this would be to make the property type generic too. That way, you'll get an appropriately strongly typed selector from the start.