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。所以,是的,这是一个