【问题标题】:OData is generating wrong URL or is it just me using wrong keywordOData 生成错误的 URL 还是只是我使用了错误的关键字
【发布时间】:2016-12-22 08:37:35
【问题描述】:

我有一个这样的查询,

https://example.com/_vti_bin/exampleService/exampleService.svc/Categories?
$filter=Products/any(x:x/Status eq toupper('DELETED'))&
$select=ID,Products/Status,Products/Title&
$expand=Products

但它不是根据 status = deleted 过滤数据集并返回状态未删除等的产品。

我查看了 SQL 跟踪,它正在生成类似这样的内容,

exec sp_executesql N'SELECT 
    [Project2].[C1] AS [C1], 
    [Project2].[C2] AS [C2], 
    [Project2].[C3] AS [C3], 
    [Project2].[ID] AS [ID], 
    [Project2].[C4] AS [C4], 
    [Project2].[C5] AS [C5], 
    [Project2].[C8] AS [C6], 
    [Project2].[ID1] AS [ID1], 
    [Project2].[C6] AS [C7], 
    [Project2].[C7] AS [C8], 
    [Project2].[Title] AS [Title], 
    [Project2].[Status] AS [Status]
    FROM ( SELECT 
        [Extent1].[ID] AS [ID], 
        1 AS [C1], 
        N''DataAccess.Product'' AS [C2], 
        N''ID'' AS [C3], 
        N''Products'' AS [C4], 
        N'''' AS [C5], 
        [Extent2].[ID] AS [ID1], 
        [Extent2].[Title] AS [Title], 
        [Extent2].[Status] AS [Status], 
        CASE WHEN ([Extent2].[ID] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE N''DataAccess.Product'' END AS [C6], 
        CASE WHEN ([Extent2].[ID] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE N''Title,Status,ID'' END AS [C7], 
        CASE WHEN ([Extent2].[ID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C8]
        FROM  [dbo].[Categories] AS [Extent1]
        LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON [Extent1].[ID] = [Extent2].[ProductID]
        WHERE ([Extent1].[ClientID] = @p__linq__0) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[Products] AS [Extent3]
            WHERE ([Extent1].[ID] = [Extent3].[ProductID]) AND (([Extent3].[Status] = (UPPER(N''DELETED''))) OR (([Extent3].[Status] IS NULL) AND (UPPER(N''DELETED'') IS NULL)))
        ))
    )  AS [Project2]
    ORDER BY [Project2].[ID] ASC, [Project2].[C8] ASC',N'@p__linq__0 int',@p__linq__0=23

如果我只想要状态为“已删除”的产品而不需要其他任何东西,使用“eq”是否正确?

编辑

我正在使用 OData V3,将 WCF 数据服务与 EF 一起使用

【问题讨论】:

  • 您的意思是在Status 上使用toupper 而不是toupper('DELETED')odata.org/documentation/odata-version-2-0/uri-conventions/…
  • @Pierre-LoupPagniez 对不起,我没有得到你?但即使我删除“toupper”结果也是一样的
  • 我的意思是:我认为您现在正在将您的StatusDELETED 的大写版本进行比较,后者已经是大写的。例如,如果您的 Status 等于 dELeteD,则您的比较将不起作用。我相信您需要在Status 上将您的电话转至toupper,例如Products/any(x:toupper(x/Status) eq 'DELETED')。不过我不确定语法,我没有办法测试我写的东西,所以你可能需要移动toupper一点。
  • @Pierre-LoupPagnez 所有数据库记录都已经是大写了
  • 哦,那我不知道,抱歉。

标签: entity-framework linq wcf sql-server-2012 odata


【解决方案1】:

我相信问题出在查询中。 形成您所说的网址,例如...

// get me categories
https://example.com/_vti_bin/exampleService/exampleService.svc/Categories?

// where any product is deleted
$filter=Products/any(x:x/Status eq toupper('DELETED'))&

// return the category id, product status and title
$select=ID,Products/Status,Products/Title&
$expand=Products

换句话说,您正在过滤已删除状态的类别,而不是其中的产品。 您可以添加第二个过滤器来处理产品过滤并仅返回类别及其过滤后的产品集。

尝试这样的事情...

https://example.com/_vti_bin/exampleService/exampleService.svc/Categories?
$filter=Products/any(x:x/Status eq toupper('DELETED'))&
$select=ID,Products/Status,Products/Title&
$expand=Products/any(p:p/Status eq toupper('DELETED'))

根据您的情况,最好将查询转过来......

https://example.com/_vti_bin/exampleService/exampleService.svc/Products?
$filter=Status eq toupper('DELETED')&
$select=Category/ID,Status,Title

...通过提取一组产品及其相关类别 ID,您可以获得相同的结果,但可以直接在基本查询中过滤这些产品,而不是更复杂的子集合过滤器。

正如聊天中所讨论的,这确实需要一个有效的 OData 模型,其中正确定义了产品和类别之间的关系。

【讨论】:

  • 谢谢,我试过了,但出现了这个错误 - 术语 'Products($filter=any(p:p/Status eq 'DELETED'))' 在 $select 或 $expand 表达式中无效.
猜你喜欢
  • 1970-01-01
  • 2019-08-31
  • 2011-01-11
  • 2019-07-22
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多