使用表达式树为LINQ查询构建IQueryable.Any [英] Build IQueryable.Any with Expression Trees for LINQ queries

查看:75
本文介绍了使用表达式树为LINQ查询构建IQueryable.Any的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm building a SQL "WHERE" clause dynamically using the System.Linq.Expressions.Expression class. It works well for simple clauses, e.g. to add "PhaseCode = X" clause, I do the following:

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

但是,现在我正在尝试构建一个表达式,如果已将项目分配给特定组,则该表达式将返回记录.项目和组具有多对多关系. 没有表达式树,我将按以下方式进行操作:

However, now I'm trying to build an expression that will returns the record if a project has been assigned to a particular group. Project and Group has many-to-many relationship. Without the expression trees, I would do it as follows:

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

但是,我似乎找不到用Expression类表达它的方法. 实际上有两件事我无法弄清:

However, I can't seem to find a way to express that with the Expression class. There are actually two things I can't figure out:

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

非常感谢您的帮助.

推荐答案

调用扩展方法,例如可枚举.Any Queryable.Any ,只是序列上的静态方法调用以及您为WHERE子句创建的lambda表达式.您可以使用 Expression.Call 来做到这一点:

Calling an extension method, like Enumerable.Any or Queryable.Any, is simply a static method call on the sequence and the lambda expression you created for the WHERE clause. You can use Expression.Call to do this:

// 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>,您需要将其汇总为一个方法:

For Queryable.Any<T>, you'll need to roll this up into a method:

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

尽管您似乎无法通过常规查询执行此操作,但这似乎很奇怪.

Although this seems odd that you're unable to do this through a normal query.

这篇关于使用表达式树为LINQ查询构建IQueryable.Any的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆