首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Expression<T、string>>转换为Expression<T、bool>>

将Expression<T、string>>转换为Expression<T、bool>>
EN

Stack Overflow用户
提问于 2014-05-05 14:16:03
回答 2查看 128关注 0票数 1

因此,我想使过滤工作自动基于一些简单的设置。我的代码是:

代码语言:javascript
复制
public ActionResult Index() // here I want to add filtering for Status I only want to show the active ones
{
    IQueryable<Ticket> cases = db.Cases().AsQueryable();
    cases = cases.EnablePaging().EnableFilterFor(x => x.Status);
    return View(cases);
}

EnableFilterFor看起来是这样的:

代码语言:javascript
复制
public static IQueryable<T> EnableFilterFor<T>(this IQueryable<T> queryable, Expression<Func<T, string>> keySelector)
{ 
    string filterValue= "Active";
    //Expression<Func<T, bool>> whereexpresion = keySelector.Compile() == "Active"

    queryable = queryable.Where(
       //here do the magic !! so that the result will be 'x=>x.Status == filterValue');
    );
    return queryable;
}

我谷歌了很多,尝试了很多不同的东西,但都没有成功。我必须将keySelector和filterValue组合起来才能工作(我需要Where方法的表达式才能工作)。任何帮助都将不胜感激。

编辑:测试两种解决方案后(谢谢!)我发现波克有最棒的。戳他的代码是唯一不改变SQL生成方式的代码。当我查看Servy生成的SQL时,它总是执行额外的Sql select查询,在WHERE子句中执行额外的和.不知道原因:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-05 14:21:14

IQueryable.Where需要一个Expression<Func<T, bool>>,所以这就是我们需要构建的东西。由于我们希望集成来自另一个表达式(一个Expression<Func<T, string>>)的东西,我们必须构建“手动”表达式。

因此,最后,我们想调用LambdaExpression.Lambda<Func<T, bool>>(…)来获取Where的表达式,但是我们需要填充表达式体:

代码语言:javascript
复制
// first, we reuse the parameter from the `keySelector` expression
ParameterExpression param = keySelector.Parameters[0];

// The body is now just an equality comparison of the `keySelector`
// body, and the constant `filterValue`
Expression body = Expression.Equal(keySelector.Body, Expression.Constant(filterValue));

// now we just need to create a lambda expression for that body with the
// saved parameter and it’s all done:
queryable = queryable.Where(Expression.Lambda<Func<T, bool>>(body, param));
票数 2
EN

Stack Overflow用户

发布于 2014-05-05 14:42:47

这里我们需要一个用于表达式的Compose方法。它将使用一个使用值的表达式,而另一个表达式在概念上将使用第一个表达式的结果作为其输入,从而生成一个新的输出。

代码语言:javascript
复制
public static Expression<Func<TFirstParam, TResult>>
    Compose<TFirstParam, TIntermediate, TResult>(
    this Expression<Func<TFirstParam, TIntermediate>> first,
    Expression<Func<TIntermediate, TResult>> second)
{
    var param = Expression.Parameter(typeof(TFirstParam), "param");

    var newFirst = first.Body.Replace(first.Parameters[0], param);
    var newSecond = second.Body.Replace(second.Parameters[0], newFirst);

    return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param);
}

它将需要将一个表达式替换为另一个表达式的能力,我们可以使用以下方法进行替换:

代码语言:javascript
复制
public static Expression Replace(this Expression expression,
    Expression searchEx, Expression replaceEx)
{
    return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}

internal class ReplaceVisitor : ExpressionVisitor
{
    private readonly Expression from, to;
    public ReplaceVisitor(Expression from, Expression to)
    {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
        return node == from ? to : base.Visit(node);
    }
}

现在我们可以写:

代码语言:javascript
复制
public static IQueryable<T> EnableFilterFor<T>(
    this IQueryable<T> queryable, 
    Expression<Func<T, string>> keySelector)
{ 
    string filterValue= "Active";

    return queryable.Where(keySelector.Compose(status => status == filterValue));
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23474724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档