Linq对WCF OData是否适用于复杂查询

时间:2013-12-18 01:57:06

标签: sql linq odata wcf-data-services

目前我们正在评估是否应该将WCF数据服务用作我们应用程序的DAL,并且我正在进行POC以查看WCF数据服务是否会破坏我们的所有方案。如果我有一个数据模型如下

DataModel

我希望获得所有产品>由Id 1订购的100美元如何使用Linq到OData,因为在使用OData时Linq运营商有许多限制。

dbContext.LineItems.Where(li => li.Order.PersonId == 1 && li.Product.Cost > 
120).Select( li => new { Product = li.Product})

上面的代码在Sql服务器上生成了非常模糊的T-SQL,理想情况下我想要从上到下(从订单到产品,如果拧干LINQ查询或直接T-SQL)加入表,但是使用OData它似乎总是从底部到顶部,我觉得不舒服,在某些情况下,当我们不得不在一个单一的查询中查询两个以上的表时,会生成非常糟糕的sql。

在我们的应用程序中,我们期待这样的场景,我们必须在单个查询中查询(写入条件)最多4个表并选择单个实体。对于这些复杂的查询,OData是否正确?

感谢阅读长篇文章。

3 个答案:

答案 0 :(得分:3)

在某些情况下,您会发现您无法在LinQ中生成Odata查询,但这不是查询不可能,只是Linq提供商可以& #39;做到了。在我们的项目开始时,我们很快发现自己首先编写了Odata查询,然后尝试将其转换为LinQ;我们花了很长时间才使用Odata来进行查询。

这篇文章可能会为您提供一些其他有用的信息:Disadvantages of OData?,尤其是关于使用视图的链接帖子。

答案 1 :(得分:1)

WCF数据服务使您可以访问DataServiceContext实例。如果您已经生成了引用,那么将为您输入。但是,您可以使用的查询运算符是有限的,与仅使用Entity Framework和Linq to Entities相比,我希望您在尝试使用它时会遇到各种程度的摩擦。

我期待这一点,因为虽然我使用的是与您的数据模型略有不同的数据模型,但它是一个类似的层次模型,我开始查询的结果与您的相同:

var query = context.DataSources.
Where(x => x.ReportLayouts[0].ReportLayoutID == 1045 &&  x.InstanceName == "hello").
Select(li => new { InstanceName = li.InstanceName });

ToList()

的结果
  

发生了类型为“System.NotSupportedException”的未处理异常   在Microsoft.Data.Services.Client.dll

中      

附加信息:表达式   (([10007] .ReportLayouts.get_Item(0).ReportLayoutID == 1045)和   ([10007] .InstanceName ==“hello”))不受支持。

为了获得这些数据,我尝试将其作为测试:

var query2 = context.DataSources.Select(x => x.ReportLayouts[0].ReportLayoutID == 1045);
var result2 = query2.ToList();
  

'System.NotSupportedException'附加信息:方法   <不支持'选择'。

然后我开始使用我的顶级实体,相当于你的Person并运行它:

var query3 = context.Reports.Where(x =>x.ReportLayoutID == 34 &&  x.DatabaseInstance.ServerName == "hello");
var result3 = query3.ToList();

这很好用。我现在正努力通过导航属性从这个顶级实体到达较低级别的实体。直接使用DataServiceContext类,我可以更轻松地编写一个DataServiceQuery,它直接转换为ODATA支持的AddQueryOption所支持的URL格式:

query = query.AddQueryOption("$expand", expandPropertyName);

这允许您通过生成类似于以下的URL来显式加载导航属性:

ReportService.svc /数据源?扩展=数据对象

生成的服务引用还提供对DataServiceContext.LoadProperty方法的访问。一旦加载,您可以查询它,但这涉及往返。

我个人不会将WCF数据服务用作您的DAL,因为这是构建实体框架的原因。如果您需要使用服务将EF模型公开给外部客户端,这是另一回事,但您的DAL应该仍然是实体框架。 WCF数据服务适用于执行非常简单的CRUD(无业务逻辑)的应用程序。对于在内部作为DAL运行的复杂查询,我不相信它。它支持的Web方法也很粗略,只接受诸如string和int之类的原语作为参数。如果需要服务,我会调查WCF,我怀疑它不是你所提到的,因为你提到将它用作DAL。

答案 2 :(得分:0)

如果您想要很好地控制OData通信,我建议使用更好地匹配OData协议的库。你可以看看我的文章“使用Simple.OData.Client消费OData feed的12个理由”,其中我提出了使用WCF数据服务的一些挑战(特别是当涉及多个实体时)以及为什么Simple.OData.Client可以更好地适应。这是链接:

http://www.codeproject.com/Articles/686240/12-reasons-to-consume-OData-feeds-using-Simple-ODa