I am working on an ASP.NET Web Api service where one of the controller actions accepts a JSON string with 0 or more Key:Value pairs to search against a collection of objects. Because of this I do not know which field names will be in the request to filter the collection on.
Now, I have code that will build dynamic query by chaining WHERE expressions based on the data provided. The problem in this case is that not only do I not know the field name which needs to be filtered on, the list of fields and their values are stored in a collection within each object - and the objects in that collection only have two properties: Name and Value.
The data is being deserialized from a bunch of XML files that I do not have control over (so cannot change the formatting), and the list of fields contained within each file could be different. (see class definition below).
[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;}
}
If I run the following query everything works fine - I get the result I am looking for based on the JSON request - however that request is only searching on one field and one value, and the query has the index of the correct field hardcoded ;) (FYI - itemList is a collection created earlier with no filtering)
itemList = (List<Bug>)itemList.Where(x => x.Fields[15].Value.ToString() == field.Value.ToString()).ToList();
I do have code in place to create a dynamic LINQ query (chaining WHERE expressions) based on the search fields provided from a JSON request (I am not including the code for this here as it is too long - and not sure it is totally relevant...YET). However, the way the expressions are being parsed you need to be able to reference the name of the property to search against - which of course is not known since it is the value of the Name property.
So - How to modify the query to take into account that field names that determine the query parameters are unknown beforehand?
EDIT: The following code block shows what I want to use (or rather that would work with my dynamic query builder). The first line is the code that works great if the field name in the class is defined the same as the field name provided in the JSON string. The second is one of the attempts I made at trying to get to the inner collection field name property.
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));
}