我正在尝试进行模块化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”。
我知道这是我的任何条款,因为如果我在声明中嵌入该条款,一切正常。
为什么我收到此错误?我怎样才能打破这个陈述而不是出错呢?
更新:使用表达式
我尝试使用这样的表达式:
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>'
答案 0 :(得分:5)
您可以尝试定义orderAnyClause,如下所示:
Expression<Func<Encounter, bool>> orderAnyClause =
x => x.OrderName.StartsWith("Order 00");
我没有测试它,但是查询理解的工作方式(并且基于错误),除非将其作为表达式获取,否则它将无法对其进行任何操作。
答案 1 :(得分:0)
您的IQueryable
需要使用expression trees才能转换查询 - 换句话说,它需要将代码视图作为数据,而不仅仅是可执行代码。
现在我并非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)
- 但是值得先尝试一下这个简单的方法。