Существует ли общий метод проверки того, поддерживает ли свойство свойство, поддерживаемое поставщиком Linq, особенно OData?

Я успешно выполнил следующую инструкцию с помощью NorthWind.sdf в LinqPad:

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?

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

Ин

Ответ 1

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

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

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

Ответ 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 для деталей и загрузки.