On a generic object, dynamic LINQ (without any hard-coded properties)

c# dynamic-linq generics linq

Question

I have a generic object that stores its attributes in a dictionary.

class MyObject 
{
    Dictionary<string, object> Properties = new Dictionary<string, object>();
    internal GetValue(string name) { return Properties[name]; }
    internal SetValue(string name, object value) { Properties[name] = value; } 
}
MyObject obj1 = New MyObject();
obj1.SetValue("Name", "John");
obj1.SetValue("Age", 23);

MyObject obj2 = New MyObject();
obj2.SetValue("Name", "Mary");
obj2.SetValue("Age", 24);

List<MyObject> ObjList = new List<MyObject>();
ObjList.Add(obj1);
ObjList.Add(obj2);

Now, in order to locate certain items, we must query the ObjList. However, from what I can see, dynamic LINQ (Flexible LINQ (Part 1: Using the LINQ Dynamic Query Library)) demands that the object contain pre-defined properties.

We wish to do searches like:

ObjList.Where("Name == 'Mary' || Age < 24");

Any token should call "GetValue," such as "Name" or "Age." Any recommendations?

It is clear that the where clause is entirely up to the user and is not fixed.

1
0
3/6/2015 9:05:13 PM

Accepted Answer

C# 4.0 allows you to have yourMyObject Execute theIDynamicMetaDataProvider property tokens are resolved to GetValue() and SetValue(), respectively, using the interface. Then, dynamic LINQ ought to function as planned.

View these words as an example.

1
11/29/2010 2:30:11 AM

Popular Answer

The Where clause's source for the Dynamic LINQ extension function is:

public static IQueryable Where(this IQueryable source, string predicate, params object[] values) {
    if (source == null) throw new ArgumentNullException("source");
    if (predicate == null) throw new ArgumentNullException("predicate");
    LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);
    return source.Provider.CreateQuery(
        Expression.Call(
            typeof(Queryable), "Where",
            new Type[] { source.ElementType },
            source.Expression, Expression.Quote(lambda)));
}

The DynamicExpression is the challenging component. Bit ParseLambda. A short scan of the source code reveals that the "ParseMemberAccess" function is part of the parsing code, which appears to imply that you may be able to accomplish things like:

ObjList.Where("GetValue('Name') == 'Mary' || GetValue('Age') < 24");

Additionally, if the parser doesn't already permit it, you might simply change it to do so.



Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow