运行时 Lambda 表达式中的多个条件 C#

发布于 2024-08-26 04:19:23 字数 1730 浏览 4 评论 0原文

我想知道如何通过输入多个参数来制作一棵表达式树

示例:

dataContext.Users.Where(u => u.username == "Username" && u.password == "Password")

目前我所做的代码如下,但希望就条件是 OR 还是 AND 做出更一般的说明

public Func<TLinqEntity, bool> ANDOnlyParams(string[] paramNames, object[] values)
    {
        List<ParameterExpression> paramList = new List<ParameterExpression>();
        foreach (string param in paramNames)
        {
            paramList.Add(Expression.Parameter(typeof(TLinqEntity), param));
        }

        List<LambdaExpression> lexList = new List<LambdaExpression>();
        for (int i = 0; i < paramNames.Length; i++)
        {
            if (i == 0)
            {
                Expression bodyInner = Expression.Equal(
                                    Expression.Property(
                                        paramList[i], paramNames[i]),
                                        Expression.Constant(values[i]));
                lexList.Add(Expression.Lambda(bodyInner, paramList[i]));
            }
            else
            {
                Expression bodyOuter = Expression.And(
                                    Expression.Equal(
                                    Expression.Property(
                                    paramList[i], paramNames[i]),
                                    Expression.Constant(values[i])),
                                    Expression.Invoke(lexList[i - 1], paramList[i]));
                lexList.Add(Expression.Lambda(bodyOuter, paramList[i]));
            }
        }

        return ((Expression<Func<TLinqEntity, bool>>)lexList[lexList.Count - 1]).Compile();
    }

谢谢

I would like to know how to be able to make an Expression tree by inputting more than one parameter

Example:

dataContext.Users.Where(u => u.username == "Username" && u.password == "Password")

At the moment the code that I did was the following but would like to make more general in regards whether the condition is OR or AND

public Func<TLinqEntity, bool> ANDOnlyParams(string[] paramNames, object[] values)
    {
        List<ParameterExpression> paramList = new List<ParameterExpression>();
        foreach (string param in paramNames)
        {
            paramList.Add(Expression.Parameter(typeof(TLinqEntity), param));
        }

        List<LambdaExpression> lexList = new List<LambdaExpression>();
        for (int i = 0; i < paramNames.Length; i++)
        {
            if (i == 0)
            {
                Expression bodyInner = Expression.Equal(
                                    Expression.Property(
                                        paramList[i], paramNames[i]),
                                        Expression.Constant(values[i]));
                lexList.Add(Expression.Lambda(bodyInner, paramList[i]));
            }
            else
            {
                Expression bodyOuter = Expression.And(
                                    Expression.Equal(
                                    Expression.Property(
                                    paramList[i], paramNames[i]),
                                    Expression.Constant(values[i])),
                                    Expression.Invoke(lexList[i - 1], paramList[i]));
                lexList.Add(Expression.Lambda(bodyOuter, paramList[i]));
            }
        }

        return ((Expression<Func<TLinqEntity, bool>>)lexList[lexList.Count - 1]).Compile();
    }

Thanks

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

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

发布评论

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

评论(1

淤浪 2024-09-02 04:19:23

Expression.And 在这里使用是错误的,它是按位与。您需要 AndAlso

除此之外,您似乎已经知道如何构建表达式树的机制。所以你真正要问的是如何让构建方法的调用者指定一种更复杂、更灵活的方式来组合不同的条件。

最终为了真正的灵活性,您需要一种迷你查询语言。解析语言以构建表达式树。

在短期内,您可能会使用更简单的东西:原始表达式列表和 bool 标志来说明它们是否应该与 && 结合使用。或||。

更新 - 我注意到您实际上正在将结果表达式编译为真正的委托。这让我想知道为什么你一开始要这么艰难地做这件事。为什么不像您最初的示例那样将表达式写为 lambda? (如果您使用的是 Linq to SQL 或 EF,则无论如何都不应该编译表达式。)

更新 2 - 您可能需要的是 动态 Linq

Expression.And is the wrong thing to use here, it's the bitwise and. You want AndAlso.

It seems like you aside from that you already know the mechanics of how to build the expression tree. So what you're really asking is how can you let the caller of your building-method specify a more complicated, flexible way of combining different conditions.

Ultimately for true flexibility you need a mini query language. Parse the language to build the expression tree.

In the short term, you might get by with something much simpler: a list of primitive expressions and a bool flag to say whether they should be combined with && or ||.

Update - I notice you're actually compiling the resulting expression into a real delegate. This makes me wonder why you're doing this the hard way in the first place. Why not just write the expression as a lambda, as in your initial example? (If you're using Linq to SQL or EF, you shouldn't be compiling the expression anyway.)

Update 2 - What you probably need is Dynamic Linq.

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