如何在Any子句中分解Linq表达式
本文关键字:分解 Linq 表达式 子句 Any | 更新日期: 2023-09-27 18:06:12
我正试图使一个模块化的Linq查询(到OData来源)。
这是我的查询的简化版本:
// Any clause that I want to be modular
Func<Encounter, bool> orderAnyClause = x => x.OrderName.StartsWith("Order 00");
// Query using the any clause
var result = entities.Customers.Where(cust=> cust.Orders.Any(orderAnyClause));
// A method to do the selection. It works just fine.
IQueryable<SearchSelectionResult> selectedResults = SelectResults(result);
// This throws the exception shown below
var list = selectedResults.ToList();
这些都编译得很好,但是当我运行它时,我的any子句导致了这个异常:
无法强制转换'System.Linq.Expressions '类型的对象。
我知道这是我的any子句,因为如果我在语句中嵌入了the子句,它就会正常工作。
为什么我得到这个错误?我怎样才能跳出这个语句而不出现错误呢?
更新:使用表达式
我试着用这样的表达:
Expression<Func<Encounter, bool>> orderAnyClause =
x => x.OrderName.StartsWith("Order 00");
我得到以下编译时错误消息:
Instance argument: cannot convert from System.Data.Services.Client.DataServiceCollection<ODataComponetizedQueriesTest.MyEntities.Order>' to 'System.Linq.IQueryable<ODataComponetizedQueriesTest.MyEntities.Order>'
您可以尝试这样定义orderAnyClause:
Expression<Func<Encounter, bool>> orderAnyClause =
x => x.OrderName.StartsWith("Order 00");
我没有测试它,但是查询理解工作的方式(基于错误),它将无法对它做任何事情,除非它得到它作为一个表达式。
您的IQueryable
需要使用表达式树来转换查询-换句话说,它需要将代码视为数据,而不仅仅是可执行代码。
现在我不能100%确定这将工作,但我希望你可以使用:
Expression<Func<Encounter, bool>> orderAnyClause =
x => x.OrderName.StartsWith("Order 00");
…然后保持相同的代码。这样,您的orderByClause
变量将引用表达式树,而不是委托。现在有可能无法工作-因为您在这里的另一个lambda表达式中使用了它:
cust => cust.Orders.Any(orderAnyClause)
…该lambda表达式也将转换为表达式树。这取决于OData提供程序用它做什么。您可能需要编写一个方法来做一些古怪的事情来构建cust.Orders.Any(orderAnyClause)
-但值得先尝试简单的方法。