我正在使用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))
但是,我似乎找不到用Expression类表达的方法。 实际上有两件我无法弄清楚的事情:
非常感谢任何帮助。
答案 0 :(得分:14)
调用扩展方法,如Enumerable.Any或Queryable.Any,只是对序列的静态方法调用以及为WHERE
子句创建的lambda表达式。您可以使用Expression.Call
执行此操作:
// for Enumerable.Any<T>(IEnumerable<T>,Predicate<T>)
var overload = typeof(Enumerable).GetMethods("Any")
.Single(mi => mi.GetParameters().Count() == 2);
var call = Expression.Call(
overload,
Expression.PropertyOrField(projParam, "GroupsAssigned"),
anyLambda);
对于Queryable.Any<T>
,您需要将其转换为方法:
static Expression BuildAny<TSource>(Expression<Func<TSource, bool>> 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;
}
虽然通过普通查询无法做到这一点似乎很奇怪。