1

我正在使用 WCF Data Services 5.2 通过 OData 查询数据库。我将在下面描述我的问题,我认为可以通过实现我自己的过滤数据的功能来解决它​​,类似于任何/全部,但如果您有更好的解决方案,请随时分享。

作为一个模型,我有一个包含员工的表,一个包含所有可能的技能(资格)的表和一个用于员工和技能之间的多对多关系的映射表(EQs)。到这里为止,一切都很简单,但技能表实际上代表了一棵技能树;例如,技能“编码”有“.Net”和 Java 作为子项,而 .Net 有 WCF 和 ASP.NET 作为子项,Java 有 JSF 和 Struts 作为子项。技能树在技能表中建模,并带有一个名为“QParentID”的列(每个技能都有一个直接父级)。

在此处输入图像描述

员工可能仅与 WCF 或 ASP.NET 作为技能有关系,但是当我搜索具有“.NET”技能的员工时,我也应该找到这些员工以及具有直接链接的员工到.NET。例如,John 拥有 WCF 和 ASP.NET 作为技能(没有直接链接到 .NET 技能),但是当我搜索具有技能 .NET 的员工时,John 也应该在结果中。实际上,我需要递归地搜索技能和他们所有的父母。

我正在考虑实现一个类似于“任何/全部”的功能。类似这样 的东西\webservice\Employees?&filter=matches(<id>) 而不是 \webservice\Employees/?$filter=EQs/any(e: e/Qualification_ID eq <id>)

这将递归地检查技能或其父级(以及父级的父级)是否与 id 匹配。

同样,如果您有比这更好的解决方案,请随时分享。

在此先感谢您的帮助。

萝莉

编辑:我添加了我想实现并与 odata 一起使用的递归函数的非优化初稿

public static bool Matches(IEnumerable<EQ> source,
int id)
    {
        if (source == null)
        {
            throw new ArgumentNullException("source");
        }
        EFEntities entities = new EFEntities();
        foreach (EQ item in source)
        {
            if (item.Qualification_ID == id || CheckParent(entities.Qualifications.Where(q=>q.ID_Qualification == id).First(),id))
            {
                return true;
            }
        }
        return false;
    }

    private static bool CheckParent(Qualification qualification, int id)
    {
        EFEntities entities = new EFEntities();
        if (qualification.ID_Qualification == id) {
            return true;
        }
        if (qualification.QParent_ID != 0) {
            if (CheckParent(entities.Qualifications.Where(q => q.ID_Qualification == qualification.ID_Qualification).First(), id)) {
                return true;
            }
        }

        return false;

    }

我从“任何”方法的实现中复制了该方法的签名,但我没有使用谓词,而是使用资格 ID 作为参数。我希望能够将其称为如下 /webservice/Employees?&filter=EQs/matches()。这可能吗?

4

1 回答 1

1

我在 MSDN 上为您回答了这个问题,但我也将答案复制到这里以提高知名度。

OData V3 协议指定了一种在元数据中声明自定义函数的方法,这些函数不仅可以用于 URI 的路径部分,还可以用于其他表达式,如 $filter。这正是您正在寻找的。http://www.odata.org/media/30002/OData.html#functions

但是,WCF 数据服务服务器目前不支持功能,因此没有简单的方法来允许您想要的功能。ASP.NET Web API 现在也不支持这个(我相信)。我不确定支持 WCF DS 或 Web API 的自定义函数的时间表,但这是我们非常希望实现的。

但是请注意,如果您的方案足够简单,则可以使用自 OData V1 以来一直存在的遗留“服务操作”。您在上面给出的确切示例可以通过以下方式在 WCF DS 中实现:

GET service\MyServiceOperationForEmployees('someStringPatternThatIWillDoSomethingFancyWith')

有关更多示例,请参阅http://www.odata.org/media/30002/OData.html#operations以及有关 WCF 数据服务上的服务操作的任何其他相关文章。这不完全是您想要的,并且从协议的角度来看已被弃用,但我建议您在准备好完整的功能支持之前尝试此操作。

于 2013-02-21T20:33:33.303 回答