2013-03-26 4 views
0

Я пытаюсь сделать модульный запрос Linq (к источнику OData).Как разбить выражение Linq внутри предложения Any

Это упрощенная версия моего запроса:

// 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(); 

Это все отлично компилируется, но когда я его запускаю мой какой-либо пункт вызывает это исключение:

Невозможно привести объект типа ' System.Linq.Expressions.ConstantExpression ', чтобы напечатать «System.Linq.Expressions.LambdaExpression».

Я знаю, что это мое предложение, потому что, если я вставляю предложение в инструкцию, все работает отлично.

Почему я получаю эту ошибку? И как я могу нарушить это утверждение и не получить ошибку?


Update: Использование Expression

Я пытался использовать выражение вроде этого:

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

ответ

5

Вы можете попробовать задать описание AnyClause так:

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

Я не проверял, но понимание способ запроса работает (и на основе ошибки), он не смог бы сделать что-нибудь с ним, если он не получает его как выражение ,

+0

Я пробовал это, и он дает ошибку времени компиляции. (Я обновил свой вопрос с сообщением об ошибке.) – Vaccano

+0

Является ли свойство Orders IEnumerable? Я предполагаю, что это так. Подпись метода расширения Enumerable.Any не принимает выражение >, поэтому вы не сможете его использовать.Вместо этого вам нужно будет создавать выражения, используя Expression.Lamba, Expression.Call и т. Д., Которые все равно все эти методы расширения. Или вы можете сделать тип ордеров IQueryable , как предлагает кто-то ниже. –

0

IQueryable должен работать с expression trees, чтобы преобразовать запрос - другими словами, он должен иметь представление о коде как данные, а не как исполняемый код.

Теперь я не 100% уверен, что это будет работать, но я бы надежду, что вы могли бы использовать:

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

... а затем сохранить тот же код. Таким образом, ваша переменная orderByClause ссылается на дерево выражений, а не на делегат. Теперь это возможно, что это не будет работать - потому что вы используете его в другом лямбда-выражения здесь:

cust => cust.Orders.Any(orderAnyClause) 

... и что лямбда-выражение будет также быть преобразованы в дерево выражения. Это действительно зависит от того, что делает поставщик OData. Вам нужно may нужно написать способ делать фанки для создания cust.Orders.Any(orderAnyClause) - но сначала стоит попробовать простой способ.

+0

Я пробовал это, но я получаю ошибку компиляции. (См. Мой обновленный вопрос об ошибке). – Vaccano

+0

@ Vaccano: Вы получаете эту ошибку * на этой линии * или позже? Кажется, странная линия, чтобы получить ошибку на ... –

+0

Это на линии, где я пытаюсь использовать orderAnyClause (вторая строка кода в моем примере.) – Vaccano

Смежные вопросы