I wonder if it is possible to query ExpandoObject with regular LINQ? Reason is that I have dynamic ExpandoObject but I need to do some querying before I can pass further.
It has some properties that always stay e.g. Id
, Notes
but also some dynamic properties that I cannot control.
Here is how my list of them looks like
[
{
"Id": 1,
"FileId": 1,
"Notes": "",
"1": "12.02.1991"
},
{
"Id": 2,
"FileId": 2,
"Notes": "",
"1": "12.02.1991"
}
]
As you can see I have my static items and then I make sure that every item dynamic keys become that item properties. In this example 1
is key and 12.02.1991
is value
var generatedItems = new List<object>();
foreach (var item in items)
{
var modifiedItem = new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("Id", item.Id),
new KeyValuePair<string, object>("FileId", item.FileId),
new KeyValuePair<string, object>("Notes", item.Notes)
};
modifiedItem.AddRange(item.Fields.Select(field => new KeyValuePair<string, object>(field.Key, field.Value)));
generatedItems.Add(ConvertToExpandoObjects(modifiedItem)); // Here I construct object from key/value pairs
}
return generatedItems; // Is it possible to query this thing?
I don't think this is relevant but here is my ConvertToExpandoObjects funciton.
public static dynamic ConvertToExpandoObjects(IEnumerable<KeyValuePair<string, object>> pairs)
{
IDictionary<string, object> result = new ExpandoObject();
foreach (var pair in pairs)
result.Add(pair.Key, pair.Value);
return result;
}
I tried to simply do something like generatedItems.Where(x => x.);
but obviously it gives me nothing to work on since it doesn't know that these objects have Id
etc..
So is it possible to query it and if so, then how?
For ExpandoObject, you can simply check whether the property is defined as a key in the underlying dictionary. For other implementations, it might be challenging and sometimes the only way is to work with exceptions.
The ExpandoObject class enables you to add and delete members of its instances at run time and also to set and get values of these members. This class supports dynamic binding, which enables you to use standard syntax like sampleObject. sampleMember instead of more complex syntax like sampleObject.
Your suggestion is right, you would be able to query a collection of dynamic objects using the dot notation.
var ids = generatedItems.Cast<dynamic>().Select(x => x.Id);
However, keep in mind that there's no type safety here and, as you stated, IntelliSense is of no use, since you're using dynamic objects.
If your code depends on whether one of those objects have an optional property (e.g., some have "Title", others don't), then it will require a little more manual labor.
if((generatedItems as IDictionary<String, object>).ContainsKey("Title")) {
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With