確かに、遅かれ早かれ、各開発者は列などでソートできるデータテーブルを作成する必要がありました。私も例外ではありません。 このプロジェクトでは、ほぼすべてのページに同様のテーブルがあり、コンテンツの90%がそれらを通して表示されていると言えます。 もちろん、テーブルによる検索とソートは、ページをリロードすることなく機能します。
もちろん、APIコントローラーメソッドのセマンティクスを無限のシートに拡張することは絶対に非現実的であり、すべてのテーブルに共通のソリューションが必要でした。 反射と表現の木は彼を見つけるのに役立ちました。
クライアントでデータを取得し、JSONオブジェクトとしてサーバーに転送するためのフィルターを作成することは、要求ファクトリーに多数の条件を掛けるよりもはるかに便利であると判断しました。
どのように見えますか
ユーザーと彼が所有する車のモデルがあるとします。
public class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public IEnumerable<Car> Cars { get; set; } } public class Car { public int CarId { get; set; } public string Model { get; set; } public int MaxSpeed { get; set; } }
名前がAで始まり、車の速度が300 km / hを超えるか、IDが0を超えるユーザーを取得し、IDの昇順で降順に並べ替えます。 これを行うには、次のオブジェクトを作成します。
{ "Where": { "OperatorType": "Or", "Operands": [ { "OperatorType": "And", "Operands": [ { "Field": "Name", "FilterType": "StartsWith", "Value": "A" }, { "Field": "Cars.MaxSpeed", "FilterType": "GreaterThan", "Value": 300 } ] }, { "Field": "Id", "FilterType": "GreaterThan", "Value": 0 } ] }, "OrderBy": [ { "Field": "Name", }, { "Field": "Flag", "Order": "Desc" } ], }
結果は、オペランドが無制限にネストされたオブジェクトであり、非常に大きなフィルターを作成できることがわかります。
このフィルターをデータ選択に適用することは残ります。 サーバーに転送し、小さなオブジェクトではなくペイントしないjsonオブジェクトをデシリアライズする方法。
FilterContainer filter = ...; // IQueryable<User> query = dataAccess.MyUsers; query = query.Request(filter); // ////query = query.Where(filter.Where).OrderBy(filter.OrderBy);
これがサンプル全体です。
Entity FrameworkまたはLinq2SQLタイプのORMは、式ツリーを使用してデータソースへの構造化クエリを表すことを、多くの人が知っていますが、知りません。 クエリプロバイダーは、式ツリーのデータ構造を調べて、クエリ言語に変換できます。
リフレクションにより、フィルターコレクターはエンティティの対応するメンバーから再帰的にクエリツリーを構築します。
githubのプロジェクトでは、すべてのろ過方法とタイプが考慮されています。
PS原則として、私はこのタスクで発見者の役職に頼りませんでした。これは既に何らかの形で行われています。 いずれにせよ、それは素晴らしい経験でした。