我正在使用 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()。这可能吗?