1

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() のように呼び出せるようにしたいと思います。それは何とか可能ですか?

4

1 に答える 1

1

私はあなたのためにMSDNでこれに答えましたが、見やすくするためにここにも答えをコピーしています.

OData V3 プロトコルは、URI のパス部分だけでなく、$filter などの他の式で使用できるメタデータでカスタム関数を宣言する方法を指定します。これはまさにあなたが探しているものです。http://www.odata.org/media/30002/OData.html#functions

ただし、WCF Data Services サーバーは現時点で関数をサポートしていないため、必要なものを許可する簡単な方法はありません。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 Data Services でのサービス操作に関するその他の関連記事を参照してください。これはまさにあなたが望むものではなく、プロトコルの観点からは非推奨ですが、完全な機能サポートの準備が整うまでこれを試すことをお勧めします.

于 2013-02-21T20:33:33.303 に答える