11

我在 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] 的实例。”。

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

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

"s.Orders.Count() as Count"   

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

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

任何建议表示赞赏。

4

2 回答 2

6

不幸的是,没有通用的编程方式来检查 LINQ 提供程序是否能够翻译任何给定的查询。通常,您必须求助于文档或(可以肯定)实际尝试查询。

但是,不同的提供者可能会提供某种机制来为查询生成某种表示,您可以使用它来检查查询是否可以工作而无需执行它。

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

于 2011-02-11T07:18:45.003 回答
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了解详细信息和下载。

于 2011-02-15T04:11:55.063 回答