0

我正在尝试进行模块化 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.ConstantExpression”类型的对象转换为“System.Linq.Expressions.LambdaExpression”类型。

我知道这是我的 any 子句,因为如果我将该子句嵌入到语句中,一切正常。

为什么我会收到此错误?我怎样才能打破这个陈述而不得到错误?


更新:使用表达式

我尝试使用这样的表达式:

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>'
4

2 回答 2

5

您可以尝试像这样定义 orderAnyClause:

Expression<Func<Encounter, bool>> orderAnyClause = 
                                        x => x.OrderName.StartsWith("Order 00");

我没有测试它,但是查询理解的工作方式(并且基于错误),除非它作为表达式得到它,否则它将无法对它做任何事情。

于 2013-03-26T20:07:47.080 回答
0

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)- 但值得首先尝试简单的方法。

于 2013-03-26T20:07:54.970 回答