我正在使用WCF Data Services 5.2通过OData查询数据库。我将在下面描述我的问题,我认为可以通过实现我自己的过滤数据功能来解决它,类似于任何/所有,但如果你有更好的解决方案,请随时分享。
作为一个模型,我有一个包含员工的表,一个包含所有可能技能(资格)的表和一个用于员工和技能之间多对多关系的映射表(EQ)。直到这里一切都很简单,但技能表实际上代表了一种技能树;例如,技术“编码”有“。Net”和Java作为子项,而.Net有WCF和ASP.NET作为子项,Java有JSF和Struts作为子项。技能树在技能表中建模,其中包含一个名为“QParentID”的列(每个技能都有一个直接父项)。
可能会发生一个员工只与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()。这有点可能吗?
答案 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数据服务上的服务操作的任何其他相关文章。这不是您想要的,并且从协议的角度来看已被弃用,但我建议您尝试使用此功能,直到完全功能支持准备就绪。