使用表达式树为LINQ查询构建IQueryable.Any

我正在使用System.Linq.Expressions.Expression类动态构建SQL“WHERE”子句。 它适用于简单的子句,例如添加“PhaseCode = X”子句,我执行以下操作:

var equalTarget = Expression.Constant(phaseCode, typeof(int?)); var phaseEquals = Expression.Equal(Expression.PropertyOrField(projParam, "PhaseCode"), equalTarget); 

但是,现在我正在尝试构建一个表达式,如果项目已分配给特定组,则该表达式将返回记录。 项目和集团有多对多的关系。 如果没有表达式树,我会按如下方式执行:

 db.Projects.Where(p => .... && p.GroupsAssigned.Any(g => g.ID == groupId)) 

但是,我似乎无法找到表达类的方法。 实际上有两件我无法弄清楚的事情:

  • 如何遍历表之间的关系
  • 如何做x.Any()

任何帮助是极大的赞赏。

调用扩展方法,如Enumerable.Any或Queryable.Any ,只是对序列的静态方法调用以及为WHERE子句创建的lambda表达式。 您可以使用Expression.Call执行此操作:

 // for Enumerable.Any(IEnumerable,Predicate) var overload = typeof(Enumerable).GetMethods("Any") .Single(mi => mi.GetParameters().Count() == 2); var call = Expression.Call( overload, Expression.PropertyOrField(projParam, "GroupsAssigned"), anyLambda); 

对于Queryable.Any ,您需要将其转换为方法:

 static Expression BuildAny(Expression> predicate) { var overload = typeof(Queryable).GetMethods("Any") .Single(mi => mi.GetParameters().Count() == 2); var call = Expression.Call( overload, Expression.PropertyOrField(projParam, "GroupsAssigned"), predicate); return call; } 

虽然这看起来很奇怪,但你无法通过普通查询来做到这一点。