OData 経由でデータベースにクエリを実行するために、WCF Data Services 5.2 を使用しています。以下に私の問題を説明します。任意/すべてと同様に、データをフィルタリングするための独自の機能を実装することで解決できると思いますが、より良い解決策がある場合は、お気軽に共有してください。
モデルとして、従業員を含むテーブル、可能なすべてのスキル (資格) を含むテーブル、および従業員とスキルの間の多対多の関係のマッピング テーブル (EQ) があります。ここまではすべて簡単ですが、スキル テーブルは実際にはスキルのツリーを表しています。たとえば、スキル「コーディング」には子として「.Net」と Java があり、.Net には子として WCF と ASP.NET があり、Java には子として JSF と Struts があります。スキル ツリーは、「QParentID」という列を持つスキル テーブルでモデル化されます (各スキルには 1 つの直接の親があります)。
従業員がスキルとして WCF または ASP.NET にのみ関連している場合がありますが、スキル ".NET" を持つ従業員を検索すると、これらの従業員も直接リンクしている従業員と一緒に取得する必要があります。 .NET に。たとえば、ジョンはスキルとして WCF と ASP.NET を持っています (.NET スキルへの直接リンクはありません) が、.NET スキルを持つ従業員を検索すると、ジョンも結果に含まれるはずです。実際には、スキルとそのすべての親を再帰的に検索する必要があります。
「any/all」に似た機能を実装することを考えていました。
\webservice\Employees?&filter=matches(<id>)
代わりに
このようなもの\webservice\Employees/?$filter=EQs/any(e: e/Qualification_ID eq <id>)
スキルまたはその親 (および親の親) が ID と一致するかどうかを再帰的にチェックします。
繰り返しますが、これよりも優れた解決策がある場合は、お気軽に共有してください。
よろしくお願いします。
ロリ
EDIT:実装して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 をパラメーターとして使用します。これを /webservice/Employees?&filter=EQs/matches() のように呼び出せるようにしたいと思います。それは何とか可能ですか?