私はASP.NETWebApiサービスに取り組んでおり、コントローラーアクションの1つが0個以上のKey:Valueペアを持つJSON文字列を受け入れて、オブジェクトのコレクションを検索します。このため、コレクションをフィルタリングするリクエストにどのフィールド名が含まれるかわかりません。
これで、提供されたデータに基づいてWHERE式をチェーンすることで動的クエリを構築するコードができました。この場合の問題は、フィルタリングする必要のあるフィールド名がわからないだけでなく、フィールドのリストとその値が各オブジェクト内のコレクションに格納され、そのコレクション内のオブジェクトには2つのプロパティしかないことです。名前と価値。
データは、私が制御できない(したがって、フォーマットを変更できない)一連のXMLファイルから逆シリアル化されており、各ファイルに含まれるフィールドのリストは異なる可能性があります。(以下のクラス定義を参照してください)。
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public class Bug
{
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public int ID { get; set; }
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public DateTime ChangedDate { get; set; }
[System.Xml.Serialization.XmlArrayAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlArrayItemAttribute("Field", typeof(BugField), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
public List<BugField> Fields {get; set;}
}
次のクエリを実行すると、すべてが正常に機能します-JSONリクエストに基づいて探している結果が得られます-ただし、そのリクエストは1つのフィールドと1つの値のみを検索し、クエリにはハードコードされた正しいフィールドのインデックスがあります;) (FYI-itemListは、フィルタリングなしで以前に作成されたコレクションです)
itemList = (List<Bug>)itemList.Where(x => x.Fields[15].Value.ToString() == field.Value.ToString()).ToList();
JSONリクエストから提供された検索フィールドに基づいて動的LINQクエリ(WHERE式をチェーンする)を作成するためのコードがあります(長すぎるため、ここにはコードを含めていません-完全に関連性があるかどうかはわかりません...まだ)。ただし、式を解析する方法では、検索するプロパティの名前を参照できる必要があります。これは、Nameプロパティの値であるため、もちろん不明です。
だから-クエリパラメータを決定するフィールド名が事前に不明であることを考慮に入れるようにクエリを変更するにはどうすればよいですか?
編集:次のコードブロックは、私が使用したいものを示しています(つまり、動的クエリビルダーで機能します)。最初の行は、クラスのフィールド名がJSON文字列で提供されるフィールド名と同じように定義されている場合にうまく機能するコードです。2つ目は、内部コレクションのフィールド名プロパティにアクセスしようとした試みの1つです。
foreach (KeyValuePair<string, object> field in queryFields)
{
itemList = itemList.Where<Bug>(field.Key, field.Value, (FilterOperation)StringEnum.Parse(typeof(FilterOperation), "eq"));
itemList = itemList.Where<Bug>(x => x.Fields.Any(y => y.Name == field.Key && y.Value == field.Value));
}