代码之家  ›  专栏  ›  技术社区  ›  kokos

在LINQ表达式树中有选择地从where子句中删除

  •  2
  • kokos  · 技术社区  · 16 年前

    从以下LINQ查询开始:

    from a in things  
    where a.Id == b.Id &&  
    a.Name == b.Name &&  
    a.Value1 == b.Value1 &&  
    a.Value2 == b.Value2 &&  
    a.Value3 == b.Value3  
    select a;
    

    如何(在运行时)删除where子句中的一个或多个条件,以获得类似于以下查询的查询:

    from a in things  
    where a.Id == b.Id &&  
    a.Name == b.Name &&  
    a.Value2 == b.Value2 &&  
    a.Value3 == b.Value3  
    select a;
    

    from a in things  
    where 
    a.Name == b.Name &&  
    a.Value3 == b.Value3  
    select a;
    
    3 回复  |  直到 16 年前
        1
  •  6
  •   Jon Skeet    16 年前

    与其尝试更改现有的where子句,不如将其重构为:

    from a in things  
    where a.Id == b.Id 
    where a.Name == b.Name 
    where a.Value1 == b.Value1
    where a.Value2 == b.Value2
    where a.Value3 == b.Value3  
    select a;
    

    然后变成:

    things.Where(a => a.Id == b.Id)
          .Where(a => a.Name == b.Name)
          .Where(a => a.Value1 == b.Value1)
          .Where(a => a.Value2 == b.Value2)
          .Where(a => a.Value1 == b.Value3);
    

    IQueryable<Whatever> query = things;
    if (useId) {
        query = query.Where(a => a.Id == b.Id);
    }
    query = query.Where(a => a.Name == b.Name);
    if (checkValue1) {
        query = query.Where(a => a.Value1 == b.Value1);
    }
    // etc
    
        2
  •  1
  •   Ali Ersöz    16 年前

    这也可能是另一种方法;

    bool executeValue1Condition = true;
    bool executeValue2Condition = true;
    bool executeValue3Condition = true;
    
    var q = from a in things  
    where a.Id == b.Id &&  
    a.Name == b.Name &&  
    (a.Value1 == b.Value1 || executeValue1Condition) &&  
    (a.Value2 == b.Value2 || executeValue2Condition) &&  
    (a.Value3 == b.Value3 || executeValue3Condition) 
    select a;
    
    executeValue1Condition = false;
    q = q.Select(i => i);
    

    通过使用这种方法,您可以在执行查询后更改条件,当然也可以通过新的执行来更改。

        3
  •  0
  •   Adrian Zanescu    16 年前

    试着把事情分开。首先将where条件与查询的其余部分隔离开来,然后对其进行处理,并使用标准的查询方法,而不是内置的语法方法。如。:

         IQueryable<MyClass> things = null;
         MyClass b = new MyClass();
    
         Expression<Func<MyClass, bool>> whereExp = a => a.Id == b.Id && a.Name == b.Name;
         // process where expression here. it's just an expression tree. traverse it and
         // remove nodes as desired.
         var result = things.Where(whereExp).Select(a => a);
    

    IQueryable<MyClass> things = null;
    MyClass b = new MyClass();
    
    Expression<Func<MyClass, bool>> whereExp;
    Expression<Func<MyClass, bool>> exp1 = a => a.Id == b.Id;
    Expression<Func<MyClass, bool>> exp2 = a => a.Name == b.Name;
    whereExp = Expression.Lambda<Func<MyClass, bool>>(Expression.And(exp1, exp2), Expression.Parameter(typeof(MyClass), "a"));
    
    var result = things.Where(whereExp).Select(a => a);