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

.net 在LINQ表达式树中有选择地从where子句中删除,.net,linq,.net,Linq,从以下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 th

从以下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;


与其尝试更改现有的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
IQueryable查询=事物;
如果(useId){
query=query.Where(a=>a.Id==b.Id);
}
query=query.Where(a=>a.Name==b.Name);
如果(检查值1){
query=query.Where(a=>a.Value1==b.Value1);
}
//等

这可能也是另一种方法

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

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

尝试将事情分开。首先将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 things=null;
MyClass b=新的MyClass();
表达式,其中exp=a=>a.Id==b.Id&&a.Name==b.Name;
//处理此处的表达式。这只是一个表达式树。穿过它,然后
//根据需要删除节点。
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);
IQueryable things=null;
MyClass b=新的MyClass();
表达式whereExp;
表达式exp1=a=>a.Id==b.Id;
表达式exp2=a=>a.Name==b.Name;
其中exp=Expression.Lambda(Expression.And(exp1,exp2),Expression.Parameter(typeof(MyClass),“a”);
var result=things.Where(whereExp).Select(a=>a);

我们这里说的是IQueryable还是IEnumerable?这可能不太好,取决于提供者。。。最好不包括它们(根据Jon的)嗯,你能说在哪种情况下?你指的是什么提供者?链式调用是否在SQL中生成和调用?如果是这样的话,您将如何使用OR实现类似的目标?如果x=y或p=r或。。。
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);