开发者

Custom expression

开发者 https://www.devze.com 2023-02-28 08:41 出处:网络
I found this example code: public IQueryable<T> Get<T>(ObjectSet<T> obj) where T : class

I found this example code:

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,开发者_JAVA技巧 bool>>)Expression.Lambda(
                Expression.Equal(
                    Expression.MakeMemberAccess(parameter, property),
                    Expression.Constant("MyValue")),
                parameter);
        //...
    }
}

What I really need is to apply a StartsWith condition (StartsWith("MyValue")) and apply another condition like >= for my another int? property.

How can I modify the code to do this?


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


First of all, consider what expression this expression tree represents.

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

is equivalent to the lambda:

it => it.MyStringField == "MyValue"

So what would you like the expression be then? From what I understand you wrote, you want something like this:

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

Well you can write this lambda and store it in an expression that way you can let the compiler perform the conversion for you:

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

Otherwise, doing it by hand:

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号