是否有一般方法来检查Linq提供程序是否支持属性定义,尤其是OData?

时间:2010-06-22 09:00:18

标签: .net linq odata

我在LinqPad中使用NorthWind.sdf成功运行了以下语句:

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

与此同时,我未能在LinqPad中对Odata服务(http://services.odata.org/northwind/northwind.svc)发表类似声明:

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

错误是“使用表达式s.Orders.Count()构造或初始化类型<> f__AnonymousType0`3 [System.Int32,System.String,System.Int32]的实例。”

我知道在Linq支持中OData服务非常有限。我在我的应用程序中有动态的Linq语句支持。实际上我正在尝试将数据源从Compact SQL Server迁移到OData服务。

所以我必须以一般方式处理NotSupportedException。目前,我尝试在运行之前检查属性define的语法,例如

"s.Orders.Count() as Count"   

它通过了我的检查,但它遇到了OData的NotSupportedException。

有没有办法检查Linq提供程序是否支持属性定义(通过字符串或lambda)?

任何建议都表示赞赏。

2 个答案:

答案 0 :(得分:6)

遗憾的是,没有通用的编程方法来检查LINQ提供程序是否能够翻译任何给定的查询。通常,您将不得不求助于文档或(确定)实际尝试查询。

但是,不同的提供程序可能会提供一些为查询生成一些表示的机制,您可以使用它来检查查询是否可以正常运行而不必执行它。

在OData客户端的情况下,您可以在查询上调用.ToString(),如果能够成功处理查询,它应该返回一个URL;否则它将返回一个类似于'错误将Linq表达式转换为URI:...'的错误消息(实际的错误消息可能会根据用户语言而改变,但它肯定不是有效的URI)。

答案 1 :(得分:2)

不幸的是,找出答案的唯一方法是测试特定查询或通过文档,如果LINQ提供程序的创建者提供了不支持的详细列表。

LINQ本身有一个非常松散的规范,主要由IQueryable / IEnumerable上定义的扩展方法定义。实现LINQ提供程序意味着您必须通过数据源实现转换 - 例如LINQ to SQL将LINQ查询中表达的表达式树转换为SQL,数据库提供程序可以理解它。每个数据源都有自己的局限性,这些局限性最终将决定支持的内容,同样每个LINQ提供程序都可以选择实现(或不实现)任何特定的方法或行为。

可能是这只是LINQPad中提供者处理OData的限制 - 你可能想要查看OQuery,看看是否为你提供了更好的功能集 - 看看{ {3}}了解详细信息并下载。