階層構造のオブジェクトのリストがあります。クライアント企業が設定し、データベースに格納されている「条件」に基づいて、そのオブジェクトリストに対して複雑なLINQクエリを作成したいと考えています。したがって、実行時にこれらを構築する必要がありますが、クライアントのユーザーがデータを更新または更新するたびに繰り返し実行されるため、LINQクエリを毎回再構築するのではなく、オブジェクトに保存したいと思います。
動的LINQに関するScottGuのブログを見てきました。
また、 式ツリーの使用に関するこの記事。
これらはどちらも適切な解決策を提供していないようですが、私はそれらを適切に理解していない可能性があります。他のオプションを検討する必要があるときに、LINQを使用しようとしていると思います。
私のオブジェクト階層:
WorkOrder[]
Field[]
Task[]
Field[]
これは、保存して実行するLINQクエリの例です。条件を定義するデータベースレコードに基づいて、このフォーマットを合理的に構築できます。
var query =
from wo in WorkOrders
from woF in wo.Fields
from task in wo.Tasks
from taskF in task.Fields
from taskF2 in task.Fields
where woF.Name == "System Status"
&& woF.Value.Contains("SETC")
&& taskF.Name == "Material"
&& taskF.Value == "Y"
&& taskF2.Name == "Planner"
&& taskF2.Value == "GR5259"
select new
{
wo_id = wo.ID,
task_id = task.ID
};
いくつかの考慮事項。
私のコードでは、次のことを想定しています。
//1) Retrieve business rules from DB. I can do this.
//2) Iterate through the business rules to build the linq queries.
foreach (BusinessRule br in BusinessRules) {
//Grab the criteria for the rule from the DB.
//Create a linq to object query based on the criteria just built.
//Add this query to a list for later use.
}
...Elsewhere in application.
//Iterate through and execute the linq queries in order to apply business rules to data cached in the application.
foreach (LinqQuery q in LinqQueries) {
//Execute the query
//Apply business rule to the results.
}
みなさんの考え、努力、アイデアに感謝します。
Guillaumeとの話し合いに基づいて、高度な動的クエリ生成をいじるときは、結果のクエリのタイプに注意を払うことをお勧めします。 Select
、 Aggregate
、またはその他のメソッドの1つを介して返されるものの形状を変更する場合は、それに応じて内部型が変更されると予想されます。 OR動作が必要でない限り、Whereで追加のケースを追加し続けることができる場所でフィルタリングしている場合は、PredicateBuilderなどが役立ちます。 Join
、 Zip
、...を介してより多くのデータを取得したい場合は、フィルター処理、返された行への追加、および場合によってはデータの形状の変更を行うことになります。
私はこれまで多くのことを行ってきましたが、最も成功したのは、必要な一般的なケースを可能にする特定のヘルパーメソッドに焦点を当て、次に実行時にカスタム式を構築できるように、linq式ツリーとビジターパターンなどのパターンを当てにしました。