0

我有一个通用对象,它使用字典来存储属性:

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);

现在我们需要查询 ObjList 以找到某些条目。动态 LINQ(动态 LINQ(第 1 部分:使用 LINQ 动态查询库))似乎很完美,但据我所知,它要求对象具有预定义的属性。

我们想做如下查询:

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

任何标记(例如姓名、年龄)都应调用“GetValue”。有什么建议么?

显然 where 语句完全取决于用户并且不是固定的。

4

2 回答 2

1

在 C# 4.0 中,您可以MyObject实现IDynamicMetaDataProvider接口,以便将属性标记分别解析为 GetValue() 和 SetValue()。然后动态 LINQ 应按预期工作。

有关示例,请参阅此帖子

于 2010-11-29T02:30:11.007 回答
1

动态 LINQ 扩展方法 Where 子句的来源是:

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)));
}

复杂的部分是 DynamicExpression.ParseLambda 位。快速浏览源代码表明解析代码包含一个“ParseMemberAccess”函数,这似乎表明您可以执行以下操作:

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

而且,如果解析器当前不允许这样做,您可以轻松地对其进行扩展,以便它这样做。

于 2010-11-28T21:41:36.843 回答