自定义表达

时间:2011-04-22 20:45:09

标签: c#-4.0 linq-to-entities expression-trees

我找到了这个示例代码:

public IQueryable<T> Get<T>(ObjectSet<T> obj) where T : class
{
    Type type = typeof(T);
    var x = type.GetInterface("IMyInterface");

    if (x != null)
    {
        var property = type.GetProperty("MyStringField");
        var parameter = Expression.Parameter(typeof(T), "it");
        Expression<Func<T, bool>> predicate =
            (Expression<Func<T, bool>>)Expression.Lambda(
                Expression.Equal(
                    Expression.MakeMemberAccess(parameter, property),
                    Expression.Constant("MyValue")),
                parameter);
        //...
    }
}

我真正需要的是应用StartsWith条件(StartsWith("MyValue"))并为我的另一个int?属性应用另一个条件,例如&gt; =。

如何修改代码才能执行此操作?

2 个答案:

答案 0 :(得分:2)

 Expression<Func<T, bool>> predicate = (Expression<Func<T, bool>>)Expression.Lambda(
                Expression.Call(Expression.MakeMemberAccess(parameter, property),
                typeof(string).GetMethod("StartsWith", new[] { typeof(string) }),
                Expression.Constant("MyValue")), parameter);

答案 1 :(得分:2)

首先,考虑这个表达式树表示的表达式。

var property = type.GetProperty("MyStringField");
var parameter = Expression.Parameter(typeof(T), "it");
Expression<Func<T, bool>> predicate =
    (Expression<Func<T, bool>>)Expression.Lambda(
        Expression.Equal(
            Expression.MakeMemberAccess(parameter, property),
            Expression.Constant("MyValue")),
        parameter);

相当于lambda:

it => it.MyStringField == "MyValue"

那么你想要表达的是什么呢?根据我的理解你写的,你想要这样的东西:

it => it.MyStringField.StartsWith("MyValue") && it.MyNullableIntField >= 12

那么你可以编写这个lambda并将它存储在一个表达式中,让你可以让编译器为你执行转换:

Expression<Func<T, bool>> predicate =
    it => it.MyStringField.StartsWith("MyValue") && it.MyNullableIntField >= 12;

否则,手动完成:

var parameter = Expression.Parameter(typeof(T), "it");
var predicate = Expression.Lambda<Func<T, bool>>(
    Expression.AndAlso(
        Expression.Call(
            Expression.Property(parameter, "MyStringField"),
            "StartsWith",
            null,
            Expression.Constant("MyValue")
        ),
        Expression.GreaterThanOrEqual(
            Expression.Property(parameter, "MyNullableIntField"),
            Expression.Convert(Expression.Constant(12), typeof(int?))
        )
    ),
    parameter
);