【问题标题】:Linq2SQL "or/and" operators (ANDed / ORed conditions)Linq2SQL“或/与”运算符(ANDed / ORed 条件)
【发布时间】:2010-11-29 21:00:21
【问题描述】:

假设我们需要应用几个条件来从名为“事物”的表中进行选择(未知计数和性质)

如果条件已知,我们可以写

db.Things.Where(t=>foo1 && foo2 || foo3);

但如果我们必须以编程方式构建 Where 条件,我可以想象我们如何应用 ANDed 条件

IQuerable DesiredThings = db.Things.AsQuerable();
foreach (Condition c in AndedConditions)
DesiredThings = DesiredThings.Where(t => GenerateCondition(c,t));

ORed 条件呢? 注意:我们不想执行联合、唯一或任何其他昂贵的操作,我们希望生成一个查询,就像我们临时编写的一样

提前致谢。


补充:

PredicateBuilder:动态组合表达式谓词

【问题讨论】:

    标签: c# .net linq-to-sql query-optimization expression-trees


    【解决方案1】:

    您可以使用带有静态方法的 Expression 类来执行它的运行时间。

    下面的代码用于创建一个委托,该委托接受一个称为 int 类型值的参数 .它从底部到顶部读取,因此有问题的行是:

    var method = LambdaExpression.Lambda(orExp, Expression.Parameter(typeof(int), "value"));
    

    方法的主体将参数的值与对新创建的 foo 类型对象的方法 Bar 的调用进行比较

    var exp2 = Expression.Equal(Expression.Parameter(typeof(int), "value"), Expression.Property(Expression.New(typeof(Foo).GetConstructor(new Type[] { })), "Bar"));
    

    然后它会创建一个类似的表达式和或它们

            var orExp = Expression.OrElse(exp1, exp2);
    

    最后是调用编译。该调用会生成一个委托,可在您的 where 方法调用中使用。

    希望它对我不是 100% 确定从参数中获取值的表达式有所帮助

    var exp1 = Expression.Equal(Expression.Parameter(typeof(int),"value"), Expression.Property(Expression.New(typeof(Bar).GetConstructor(new Type[] { })), "Foo"));
                var exp2 = Expression.Equal(Expression.Parameter(typeof(int), "value"), Expression.Property(Expression.New(typeof(Foo).GetConstructor(new Type[] { })), "Bar"));
                var orExp = Expression.OrElse(exp1, exp2);
                var method = LambdaExpression.Lambda(orExp, Expression.Parameter(typeof(int), "value"));
                method.Compile();
    

    如果您需要将 LambdaExpression 转换为不同于二进制代码的内容(例如,转换为 SQL 语句),您可能希望查看调用的调用而不是编译表达式

    【讨论】:

    • 这实际上应该是Expression.OrElse,以便与||直接比较;如果它用于 LINQ-to-SQL,您不想使用 Compile
    • @Marc 您当然是对的,它应该是 OrElse,我还为您评论的第二部分扩展了最后一段。谢谢
    【解决方案2】:

    对于OR,您有两种选择:

    • 使用Union/Concat
    • 在代码中写入Expression

    第二个更接近.Where(x => {a} || {b})

    如果您使用的是 LINQ-to-SQL,则可以使用 Expression.Invoke 组合多个单独的 lambda 表达式 (see this answer) - 但是,实体框架不支持此功能。在 EF 中,您必须使用 Expression.OrElse 将整个表达式构建为单个块;例如herehere

    【讨论】:

      猜你喜欢
      • 2014-01-11
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 2022-01-07
      • 2023-03-03
      • 1970-01-01
      • 2017-05-08
      • 2017-04-13
      相关资源
      最近更新 更多