4

私の質問は次のとおりです。ナビゲーション プロパティのデフォルトのサーバー側「フィルター」をどのように実装できますか?

私たちのアプリケーションでは、実際にデータベースから何かを削除することはめったにありません。Deleted代わりに、各テーブルにビット列がある「ソフト削除」を実装します。この列が true の場合、レコードは「削除」されています。false の場合、そうではありません。

これにより、クライアントによって誤って削除されたレコードを簡単に「元に戻す」ことができます。

現在の ASP.NET Web API は、クライアントからdeleted引数が送信されない限り、デフォルトで「削除されていない」レコードのみを返しtrueます。これは、サービスの利用者が、削除されていないアイテムのみが必要であると指定することを心配する必要がないという考え方です。

これと同じ機能を Breeze に実装するのは、少なくともベース エンティティの場合は非常に簡単です。たとえば、「削除済み」ビット フィールドを追加して、従来の Todo の例を実装すると、次のようになります。

    // Note: Will show only undeleted items by default unless you explicitly pass deleted = true.
    [HttpGet]
    public IQueryable<BreezeSampleTodoItem> Todos(bool deleted = false) {
        return _contextProvider.Context.Todos.Where(td => td.Deleted == deleted);
    }

クライアント側で行う必要があるのは...

var query = breeze.EntityQuery.from("Todos");

...削除されていないすべての Todo を取得するには、または...

var query = breeze.EntityQuery.from("Todos").withParameters({deleted: true})

...削除されたすべての Todo を取得します。

しかし、BreezeSampleTodoItem に、その Todo を完了するために必要なツールの子コレクションがあるとします。これを「ツール」と呼びます。ツールは論理的な削除も実装します。ツールで Todo を取得するために使用するクエリを実行するexpandと、すべてのツールが「削除済み」かどうかにかかわらず返されます。

しかし、展開されたときにデフォルトでこれらのレコードを除外するにはどうすればよいTodo.Toolsですか?

展開が必要な項目ごとに個別の Web API メソッドを用意することにしました。たとえば、次のようになります。

[HttpGet]
public IQueryable<Todo> TodoAndTools(bool deletedTodos = false, bool deletedTools = false)
{
    return // ...Code to get filtered Todos with filtered Tools
}

別の SO 投稿でこれを行う方法のサンプル コードを見つけましたが、Todo の各プロパティを手作業でコーディングする必要があります。上記の投稿のコードも、Listではなくを返しますIQueryable。さらに、これには、考えられるすべての拡張に対してメソッドを追加する必要があり、クールではありません。

基本的に私が探しているのは、クエリが実行されるたびに呼び出されるコードとTodos、クエリが実行されるたびに呼び出されるコードを定義する方法Toolsです。できれば、削除されたアイテムを返す必要があるかどうかを定義する引数を渡すことができます。これは、サーバー側スタックのどこにでもある可能性があります - Web API メソッド自体、または Entity Framework の一部である可能性があります (インクルード拡張機能のフィルタリングは EF ではサポートされていないことに注意してください)。

4

1 に答える 1

1

「エキスパンド」のフィルタリングを許可するというアイデアについては議論しましたが、Breeze は現在あなたが求めていることを正確に行うことはできませんが、コミュニティがこれを有用と考えるかどうかについては、さらに多くのフィードバックが必要です. ぜひbreezeのユーザーボイスに追加して投票してください。私たちはこれらの提案を非常に真剣に受け止めています。

さらに、ご指摘のとおり、EF はこれをサポートしていません。

しかし...できることは、展開の代わりに投影を使用して、非常に似たようなことを行うことです:

public IQueryable<Object> TodoAndTools(bool deleted = false
                                      ,bool deletedTools = false) {
    var baseQuery = _contextProvider.Context.Todos.Where(td => td.Deleted == deleted);
    return baseQuery.Select(t => new {
      Todo: t,
      Tools: t.Tools.Where( tool => tool.Deleted = deletedTools);
    });
 }

ここで注意すべき点がいくつかあります。

1) ToDo の IQueryable ではなく、Object の IQueryable を返しています。

2) Breeze は返されたペイロードを検査し、返されたすべての「entityTypes」に対して Breeze エンティティを自動的に作成します (プロジェクション内であっても)。したがって、このクエリの結果は、それぞれ 2 つのプロパティを持つ JavaScript オブジェクトの配列になります。「ToDo」と「Tools」。Tools は「Tool」エンティティの配列です。良い点は、プロジェクション内で返される ToDo エンティティとツール エンティティの両方が「完全な」簡単なエンティティになることです。

3) 投影されたプロパティ名に基づいて、クライアント側のフィルターを渡すことができます。すなわち

var query = EntityQuery.from("TodoAndTools")
        .where("Todo.Description", "startsWith", "A")
        .using(em);

4) EFこれをサポートしています。

于 2013-01-30T21:44:01.870 に答える