2010-06-22 1 views
11

я успешно провел следующее заявление с Northwind.sdf в LINQPad:Существует ли общий метод проверки того, поддерживается ли свойство, поддерживаемое поставщиком Linq, особенно OData?

from s in Shippers 
    select new 
{ 
    s.ShipperID, 
    s.CompanyName,  
    Count=s.ShipViaOrders.Count()  
} 

В то же время, мне не удалось запустить аналогичное заявление с OData службы (http://services.odata.org/northwind/northwind.svc) в LINQPad:

from s in Shippers  
select new 
{ 
    s.ShipperID, 
    s.CompanyName,  
    Count=s.Orders.Count()  
} 

Ошибка: «Построить или инициализировать экземпляры типа <> f__AnonymousType0`3 [System.Int32, System.String, System.Int32] с выражением s.Orders.Count() не поддерживается.".

Я знаю, что сервис OData очень ограничен в поддержке Linq. У меня есть динамическая поддержка операторов Linq в моем приложении. На самом деле я пытаюсь перенести источник данных из Compact SQL Server в службу OData.

Так что мне приходится иметь дело с NotSupportedException в общем виде. В настоящее время, я стараюсь, чтобы проверить синтаксис собственности определить перед его запуском, такой, как

"s.Orders.Count() as Count" 

Он прошел мой чек, но он встретил NotSupportedException из OData.

Есть ли способ проверить, определяется ли свойство (строкой или лямбдой) поставщиком Linq?

Любые предложения приветствуются.

Ин

ответ

6

К сожалению, нет никакого общего программного способа проверки, будет ли поставщик LINQ иметь возможность перевести любой данный запрос. Как правило, вам придётся прибегнуть к документации или (конечно) на самом деле опробовать запросы, как вы это делаете.

Различные поставщики могут, однако, предоставить некоторый механизм генерации некоторого представления для запроса, который вы можете использовать для проверки того, будет ли запрос работать без его выполнения.

В случае клиента OData вы можете вызвать .ToString() в запросе и вернуть URL-адрес, если он сможет успешно обработать запрос; в противном случае оно вернет сообщение об ошибке, похожее на «Ошибка перевода выражения Linq в URI: ...» (фактическое сообщение об ошибке может измениться в зависимости от языка пользователя, но оно будет определенно не будет действительным URI).

+0

@Ying: Это звучит как * * ответ на меня. Если это так, вы можете принять его. – chiccodoro

2

К сожалению, единственный способ узнать это - проверить конкретный запрос или документацию, если создатель провайдера LINQ предоставил подробный список того, что не поддерживается.

LINQ сам имеет очень слабую спецификацию, в основном определяемую методами расширения, определенными в IQueryable/IEnumerable. Внедрение LINQ-провайдера означает, что вам необходимо реализовать перевод по источнику данных - например, LINQ to SQL преобразует дерево выражений, выраженное в запросе LINQ в SQL, которое понимает поставщик базы данных. Каждый источник данных имеет свои собственные ограничения, которые в конечном итоге будут регулировать то, что можно поддерживать, а также каждый поставщик LINQ может выбрать реализацию (или не реализацию) какого-либо конкретного метода или поведения.

Возможно, это просто ограничение поставщика внутри LINQPad для работы с OData - вы можете вместо этого проверить OQuery и посмотреть, обеспечивает ли это лучший набор возможностей для вас - посмотрите на http://beta.code.msdn.microsoft.com/OQuery-Building-OData-d2e75eed для деталей и загрузки.

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