我有以下代码;
IQueryable<MyClass> query = listOfObjects.Where(x => x.SomeProp == 1);
Run Code Online (Sandbox Code Playgroud)
我将此传递给一个特定API的方法,该方法期望IQueryable,这很好.
但是,我想动态构建谓词,所以我正在使用它Expression.Lambda
来实现这一点,然后我.Compile
将它转回一个Func<MyObject, bool>
.
我原以为以下会有效;
Func<MyClass, bool> predicate = x => GetPredicate();
IQueryable<MyClass> query = list.Fields.Where(predicate);
Run Code Online (Sandbox Code Playgroud)
但是,传递predicate
给Where
已经将返回类型更改为IEnumerable<MyClass>
,这显然不是API所需的类型.
我做了(天真地)尝试predicate.AsQueryable()
,但有问题的API(SharePoint客户端对象模型)失败了,通用的"不支持指定的方法".错误信息.
我不知道这是LINQ提供程序的局限性,但是无论如何......我很想理解为什么将其Func
拉出到自己的变量中并将其传入以Where
影响类型推断的方式它确实.
小智 7
IQueryable
正在使用表达式树来构建谓词.所以,而不是
Func<MyClass, bool> predicate = x => GetPredicate();
Run Code Online (Sandbox Code Playgroud)
使用:
Expression<Func<MyClass, bool>> predicate = x => GetPredicate();
Run Code Online (Sandbox Code Playgroud)
请记住:使用IQueryable
表达式树时(树表示在集合上进行的操作(作为操作数和参数)).为了将树转换为其他形式(假设sql查询,取决于LINQ proider),转换器必须知道树中使用的所有操作数.看起来你正在传递的服务中的转换器IQueryable
不知道GetPredicate
函数做了什么(并且不知道如何将它转换为sql查询)所以抛出不支持的异常..
同样的事情是Func而不是Expression.Func是谓词的编译版本(存储为委托) - 提供者不知道如何翻译代理.使用Expression时,谓词将存储为树,因此提供程序可以"查看"表达式并正确转换它.
归档时间: |
|
查看次数: |
673 次 |
最近记录: |