Is there a general method to check whether a property define supported by a Linq provider, especially OData?
I successfully ran the following statement with the NorthWind.sdf in LinqPad:
from s in Shippers
select new
{
s.ShipperID,
s.CompanyName,
Count=s.ShipViaOrders.Count()
}
At the same time , I failed to run a similar statement with the Odata Service (http://services.odata.org/northwind/northwind.svc) in LinqPad:
from s in Shippers
select new
{
s.ShipperID,
s.CompanyName,
Count=s.Orders.Count()
}
The error is "Constructing or initializing instances of the type <>f__AnonymousType0`3[System.Int32,System.String,System.Int32] with the expression s.Orders.Count() is not supported.".
I know OData service is very limited in Linq Support. I have dynamic Linq statement support in my application. Actually I am trying to migrate the datasource from Compact SQL Server to OData service.
So I h开发者_如何学编程ave to deal with NotSupportedException in a general way. At present, I try to check the syntax of property define before running it, such as
"s.Orders.Count() as Count"
It passed my check, but it met NotSupportedException of OData.
Is there a way to check whether a property define (by a string or lambda) is supported by a Linq provider?
Any suggestions are appreciated.
Ying
Unfortunately there is no general programmatic way of checking whether a LINQ provider will be able to translate any given query. Typically you'll have to resort to documentation or (to be sure) actually try out the queries as you are doing.
Different providers may, however, provide some mechanism of generating some representation for the query, which you may be able to use to check whether the query would work without having to execute it.
In the OData client case, you can invoke .ToString() on the query, and it should return a URL if it's able to successfully process the query; otherwise it will return an error message that looks similar to 'Error translating Linq expression to URI: ...' (the actual error message may change depending on the user language, but it will definitely not be a valid URI).
Unfortunately the only way to find out is by testing a specific query or via documentation if the creator of the LINQ provider has provided a detailed list of what is not supported.
LINQ itself has a very loose specification largely defined by the extension methods defined on IQueryable/IEnumerable. Implementing a LINQ provider means you have to implement a translation over the data source - e.g. LINQ to SQL translates the expression tree expressed in a LINQ query into SQL which is understood by a database provider. Each data source has its own limitations which will ultimately govern what can be supported, and likewise each LINQ provider can choose to implement (or not implement) any particular method or behavior.
It may be the case that this is just a limitation of the provider inside LINQPad for dealing with OData - you might want to check out OQuery instead and see if that provides a better set of capabilities for you - have a look at http://beta.code.msdn.microsoft.com/OQuery-Building-OData-d2e75eed for the details and a download.
精彩评论