在动态Linq中合并

时间:2012-02-29 15:33:21

标签: c# linq dynamic-linq

我正在使用Dynamic Linq来查询我们的数据库,该字符串是根据用户输入的过滤器创建的。在一种情况下,我们需要在两个字段上执行合并,以便将过滤器应用于结果。

结果语法如下所示:

(nullableField ?? requiredField) == "foo"

或者,如果使用扩展方法:

(nullableField ?? requiredField).Contains("foo")

动态Linq,或者至少我们目前在我们的项目中拥有的版本,不支持合并,是否有可用的实现或关于如何实现我自己的建议?我对表达式的经验很少,而且我很难创建自己的表达式。到目前为止,以下代码适用于我的有限测试,但我不确定我是否已正确完成。

这由ParseExpression()调用:

    // ?? operator
    Expression ParseCoalesce()
    {
        Expression left = ParseLogicalOr();
        if (token.id == TokenId.DoubleQuestion)
        {
            NextToken();
            Expression expr1 = ParseExpression();
            left = Expression.Coalesce(left, expr1);
        }
        return left;
    }

对此代码的想法?有没有更好的方法呢?

2 个答案:

答案 0 :(得分:1)

如果您的系统支持ConditionalExpression,则可以像

一样实施
(nullableField != null ? nullableField == "foo" : requiredField == "foo")

(nullableField != null ? nullableField : requiredField) == "foo"

答案 1 :(得分:0)

使这个问题从死里复活,因为它似乎是唯一与动态linq中的凝聚运算符有关的问题。我一直在构建的版本可以处理ParseExpression中的三元运算符,因此我只是对其进行了扩展,类似于您的操作方式:

    Expression ParseExpression()
    {
        int errorPos = token.pos;
        Expression expr = ParseLogicalOr();
        if (token.id == TokenId.Coalesce)
        {
            NextToken();
            Expression expr1 = ParseExpression();
            expr = Expression.Coalesce(expr, expr1);
        }
        else if (token.id == TokenId.Question)
        {
            NextToken();
            Expression expr1 = ParseExpression();
            ValidateToken(TokenId.Colon, Res.ColonExpected);
            NextToken();
            Expression expr2 = ParseExpression();
            expr = GenerateConditional(expr, expr1, expr2, errorPos);
        }
        return expr;
    }

由于我遇到了缺少的功能(于是,在等等),我一直将其添加到位于此处的自定义库中:

https://github.com/jayoungers/DynamicExpressions/tree/master/DynamicExpressions/Linq

它在NuGet中以DynamicExpressions的形式提供