如何在OData查询中使用$ filter

时间:2013-01-17 13:27:22

标签: linq wcf-data-services odata windows-store-apps

我在Windows 8商店应用程序中使用OData服务时遇到问题。

如果我这样做:

IEnumerable<vw_mobSurveyor> lstSurveyors =
    await ((DataServiceQuery<vw_mobSurveyor>)ODataContext.vw_mobSurveyor
        .AddQueryOption("$filter", "intSurveyorID eq " + intID.ToString()))
        .ExecuteAsync("GetByID").ConfigureAwait(false);

它可以工作,URI的结尾是:/vw_mobSurveyor?$filter=intSurveyorID eq 1。如果我在浏览器中尝试它,这个URI也可以工作,所以一切都很好。

但如果我这样做:

IEnumerable<vw_mobSurveyor> lstSurveyors = 
    await ((DataServiceQuery<vw_mobSurveyor>)ODataContext.vw_mobSurveyor
        .Where(s => s.intSurveyorID == intID))
        .ExecuteAsync("GetByID").ConfigureAwait(false);

这会因客户端内部错误4而失败。它会产生不同的URI结尾:/vw_mobSurveyor(2)当我在浏览器中尝试此URI时,此URI失败,这就是代码生成时失败的原因。< / p>

我已经读过这两个在生成的URI中应该是等价的:http://msdn.microsoft.com/en-us/library/ee622463.aspx#filtering

因为我希望将来传递一个Linq表达式,所以我需要让第二个版本工作。那么如何强制第二个版本使用$filter以便它可以工作呢?

使用$ filter

更新:工作代码的Fiddler输出
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Length: 1057
Content-Type: application/atom+xml;type=feed;charset=utf-8
Server: Microsoft-IIS/7.0
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 18 Jan 2013 11:35:34 GMT

<?xml version="1.0" encoding="utf-8"?>
<feed xml:base="http://MYSERVER/TESTAPP%20V1/DataService.svc/"
xmlns="http://www.w3.org/2005/Atom"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <id>http://MYSERVER/TESTAPP%20V1/DataService.svc/vw_mobSurveyor</id>
  <title type="text">vw_mobSurveyor</title>
  <updated>2013-01-18T11:35:34Z</updated>
  <link rel="self" title="vw_mobSurveyor" href="vw_mobSurveyor" />
  <entry>
    <id>http://MYSERVER/TESTAPP%20V1/DataService.svc/vw_mobSurveyor(2)</id>
    <category term="SurveyProModel.vw_mobSurveyor" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <link rel="edit" title="vw_mobSurveyor" href="vw_mobSurveyor(2)" />
    <title />
    <updated>2013-01-18T11:35:34Z</updated>
    <author>
      <name />
    </author>
    <content type="application/xml">
      <m:properties>
        <d:intSurveyorID m:type="Edm.Int32">2</d:intSurveyorID>
        <d:vchName>Bob Green 2</d:vchName>
        <d:vchStatus>Surveyor</d:vchStatus>
      </m:properties>
    </content>
  </entry>
</feed>

更新:Fiddler输出失败的代码

HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Length: 824
Content-Type: application/atom+xml;type=entry;charset=utf-8
Server: Microsoft-IIS/7.0
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 18 Jan 2013 11:33:30 GMT

<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="http://MYSERVER/TESTAPP%20V1/DataService.svc/"
xmlns="http://www.w3.org/2005/Atom"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <id>http://MYSERVER/TESTAPP%20V1/DataService.svc/vw_mobSurveyor(2)</id>
  <category term="SurveyProModel.vw_mobSurveyor" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
  <link rel="edit" title="vw_mobSurveyor" href="vw_mobSurveyor(2)" />
  <title />
  <updated>2013-01-18T11:33:30Z</updated>
  <author>
    <name />
  </author>
  <content type="application/xml">
    <m:properties>
      <d:intSurveyorID m:type="Edm.Int32">2</d:intSurveyorID>
      <d:vchName>Bob Green 2</d:vchName>
      <d:vchStatus>Surveyor</d:vchStatus>
    </m:properties>
  </content>
</entry>

2 个答案:

答案 0 :(得分:0)

看起来你在查询视图;你在实体模型中设置了实体键属性吗?

答案 1 :(得分:0)

这似乎是WCF数据服务客户端中的一个错误。

乍一看,我没有看到你提供的Fiddler痕迹有任何问题,但我会尝试在我的最后重现这个问题,我会为此提出内部错误。如果您有错误的完整堆栈跟踪,那将非常有用。

请注意:LINQ-to-URI转换位在这里做的正确。如果.Where子句仅检查实体的键值,我们通过直接通过其键(即../vw_mobSurveyor(2))查找实体来优化查询,而不是使用{{1}机制。这将导致输入响应有效负载而不是馈送,这与您从Fiddler获得的匹配。

要回答您的原始问题,您可以通过使谓词涉及除了实体键之外的任何内容来强制LINQ转换器使用$filter。例如,您可以执行以下操作:

$filter

这显然是一个黑客,但它应该工作。理想情况下,我们会找到并修复此错误,然后您可以使用更正常的Where子句:)。