C# 转换表达式<;T、 字符串>&燃气轮机;表达<;T、 布尔>&燃气轮机;

C# 转换表达式<;T、 字符串>&燃气轮机;表达<;T、 布尔>&燃气轮机;,c#,linq,generics,C#,Linq,Generics,因此,我想根据一些简单的设置自动进行过滤。我的代码是: 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

因此,我想根据一些简单的设置自动进行过滤。我的代码是:

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);
}
public ActionResult Index()//我想在这里添加状态筛选,我只想显示活动状态
{
IQueryable cases=db.cases().AsQueryable();
cases=cases.EnablePaging().EnableFilterFor(x=>x.Status);
返回视图(案例);
}
EnableFilter的外观如下所示:

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;
}
公共静态IQueryable启用筛选器(此IQueryable可查询,表达式键选择器)
{ 
字符串filterValue=“活动”;
//表达式whereexpresion=keySelector.Compile()=“活动”
queryable=queryable.Where(
//在这里做魔术!!这样结果将是'x=>x.Status==filterValue');
);
返回可查询;
}
我在谷歌上搜索了很多,尝试了很多不同的东西,但都没有成功。我必须以某种方式将keySelector和filterValue结合起来才能工作(我需要一个Where方法的表达式)。任何帮助都将不胜感激


编辑:在测试了这两种解决方案之后(谢谢大家!)我发现Poke的解决方案是最好的。Poke的代码是唯一不会改变SQL生成方式的代码。当我查看Servy his生成的SQL时,它总是执行额外的SQL select查询,并在WHERE子句中执行额外的and。。。不知道为什么:)

IQueryable。其中
需要一个
表达式,因此这将是我们需要构建的东西。当我们想要集成来自另一个表达式(a
表达式
)的内容时,我们必须“手动”构建表达式

最后,我们想调用
LambdaExpression.Lambda(…)
来获得
的表达式,其中
,但我们需要填充表达式体:

// 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));
//首先,我们重用'keySelector'表达式中的参数
ParameterExpression param=keySelector.Parameters[0];
//主体现在只是“keySelector”的相等比较`
//body和常量'filterValue`
表达式体=表达式.Equal(keySelector.body,表达式.Constant(filterValue));
//现在我们只需要用
//已保存参数并已全部完成:
queryable=queryable.Where(Expression.Lambda(body,param));

IQueryable。其中
需要一个
表达式
,因此这将是我们需要构建的东西。当我们想要集成来自另一个表达式(a
表达式
)的内容时,我们必须“手动”构建表达式

最后,我们想调用
LambdaExpression.Lambda(…)
来获得
的表达式,其中
,但我们需要填充表达式体:

// 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));
//首先,我们重用'keySelector'表达式中的参数
ParameterExpression param=keySelector.Parameters[0];
//主体现在只是“keySelector”的相等比较`
//body和常量'filterValue`
表达式体=表达式.Equal(keySelector.body,表达式.Constant(filterValue));
//现在我们只需要用
//已保存参数并已全部完成:
queryable=queryable.Where(Expression.Lambda(body,param));

这里我们需要的是一个用于表达式的
Compose
方法。它将接受一个使用值的表达式,以及另一个概念上使用第一个表达式的结果作为输入的表达式,并生成一个新的输出

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);
}
现在我们可以写:

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));
}
公共静态IQueryable启用筛选器(
这是一个可以质疑的问题,
表达式(键选择器)
{ 
字符串filterValue=“活动”;
返回queryable.Where(keySelector.Compose(status=>status==filterValue));
}

这里我们需要的是一个用于表达式的
Compose
方法。它将接受一个使用值的表达式,以及另一个概念上使用第一个表达式的结果作为输入的表达式,并生成一个新的输出

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);
}
现在我们可以写:

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));
}
公共静态IQueryable启用筛选器(
这是一个可以质疑的问题,
表达式(键选择器)
{ 
字符串filterValue=“活动”;
返回queryable.Where(keySelector.Compose(status=>status==filterValue));
}

-1因为你肯定可以使用
函数
,从这个意义上说,没有人阻止你。但是如果是这样的话,参数和返回值就不会是
IQueryable
@Maximc您意识到这会导致整个数据库表被拉下来并进入内存,而不是让数据库过滤项目,对吗?更新了我的答案,但我不知道
IQueryable
的不同重载。谢谢@Jon@poke在
IQueryable
上的
Where
重载并没有什么不同<代码>IQueryable
扩展了
IEnumerable
。这是使用
Where
IEnumerable
重载,而不是
IQueryable
重载,这意味着这一切都是在LINQ to对象中完成的。@请注意,我原来的答案使用的是while,现在我的答案使用的是while。因此,是的,这是一个不同的“重载”。-1因为确保您可以使用
Func
,从这个意义上说,没有人阻止您。但是如果是这样的话,参数和返回值就不会是
IQueryable
@Maximc您意识到这会导致整个数据库表被拉下来并进入内存,而不是让数据库过滤项目,对吗?更新了我的答案,但我不知道
IQueryable
的不同重载。谢谢@Jon@poke在
IQueryable
上的
Where
重载并没有什么不同<代码>IQueryable扩展了
IEnumerable
。这是使用
Where
IEnumerable
重载,而不是
IQueryable
重载,这意味着这一切都是在LINQ to对象中完成的。@请注意,我原来的答案使用的是while,现在我的答案使用的是while。所以,是的,这是一个