Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to query list of ExpandoObject?

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"
  }
]

Code

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?

like image 824
Stan Avatar asked Sep 11 '13 16:09

Stan


People also ask

How do I know if I have ExpandoObject property?

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.

What is ExpandoObject in C#?

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.


1 Answers

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")) {

}
like image 177
dcastro Avatar answered Sep 28 '22 09:09

dcastro