WCF数据服务“任何/所有”之类的功能

时间:2013-02-18 17:08:21

标签: c# .net linq wcf-data-services odata

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

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

enter image description here

可能会发生一个员工只与WCF或ASP.NET有关系的技能,但当我搜索具有“.NET”技能的员工时,我应该让这些员工和那些员工一起直接链接到.NET。例如,John有WCF和ASP.NET作为技能(没有直接链接到.NET技能)但是当我搜索具有.NET技能的员工时,John也应该在结果中。实际上,我需要通过技能和他们所有的父母递归搜索。

我正在考虑实现一个类似于“any / all”的功能。这样的事情 \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;

    }

我从“any”方法的实现中复制了方法的签名,但是我使用了资格id作为参数而不是Predicate。我希望能够将其称为如下/ webservice / Employees?&amp; filter = EQs / matches()。这有点可能吗?

1 个答案:

答案 0 :(得分: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中实现:

获取服务\ MyServiceOperationForEmployees('someStringPatternThatIWillDoSomethingFancyWith')

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