Entity framework OData生成了错误的URL,还是只是我使用了错误的关键字

Entity framework OData生成了错误的URL,还是只是我使用了错误的关键字,entity-framework,linq,wcf,sql-server-2012,odata,Entity Framework,Linq,Wcf,Sql Server 2012,Odata,我有一个这样的疑问 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 exec sp_executesql N'SELECT [Projec

我有一个这样的疑问

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
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
但它不会根据status=deleted过滤数据集,并返回状态为not deleted的产品等

我查看了SQL跟踪,它生成了如下内容

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
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”是否正确

编辑


我使用的是ODataV3,将WCF数据服务与EF一起使用,我相信问题出在查询中。 形成你所说的url类似于

// 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模型,其中正确定义了产品和类别之间的关系。

您的意思是在
状态上使用
toupper
而不是
toupper('DELETED')
@Pierre LoupPagniez很抱歉我没抓住你?但是,即使我删除了“toupper”,结果也是一样的。我的意思是:我认为现在你正在将你的
状态
已删除
的大写版本进行比较,后者已经是大写了。例如,如果您的
状态
等于
已删除
,则比较将无效。我认为您需要在
Status
上将呼叫移动到
toupper
,就像
Products/any(x:toupper(x/Status)eq'DELETED')
。虽然我不确定语法,但我没有任何方法来测试我写的内容,因此您可能需要稍微移动
toupper
。@Pierre LoupPagniez所有数据库记录都已使用大写字母哦,那么我不知道,抱歉。谢谢,我尝试过,但得到了这个错误-术语“产品($filter=any(p:p/Status eq'DELETED'))'在$select或$EXPLAND表达式中无效。