自定义表达

发布于 2024-11-02 22:42:22 字数 827 浏览 3 评论 0原文

我找到了这个示例代码:

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? 应用另一个条件,例如 >= > 财产。

我该如何修改代码来做到这一点?

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, 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

素衣风尘叹 2024-11-09 22:42:22
 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);
 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);
我的痛♀有谁懂 2024-11-09 22:42:22

首先,考虑一下这个表达式树代表什么表达式。

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

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
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文