如何创建动态Lambda表达式
本文关键字:动态 Lambda 表达式 创建 何创建 | 更新日期: 2023-09-27 18:04:38
我有一个问题,我如何添加另一个过滤器,这个我必须验证被选中?
private Expression < Func < Entity.Modelos.Flux, bool >> Filter() {
var dateStart = dtpDateStart.Value.Date;
var dateEnd = dtpDateEnd.Value.Date;
Expression < Func < Entity.Modelos.Flux, bool >> expr = null;
expr = f = > f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date;
if (txtDescription.Text != String.Empty) {
//add filter
}
return expr;
}
更新:我将在这个函数中使用表达式:
public virtual IQueryable < T > Filter(Expression < Func < T, bool >> expressao) {
return DbSet.Where(expressao).AsQueryable < T > ();
}
我想做的是这个,但是用一个表达式
public List < Users > GetUsers(int ? id, string name) {
using(DBContext ctx = new DBContext()) {
IQueryable query = ctx.Usuarios;
if (id.HasValue)
query = query.Where(x = > x.ID == id);
if (!string.IsNullOrEmpty(name))
query = query.Where(x = > x.Name.StartsWith(name));
return query.ToList();
}
}
inherit from ExpressionVisitor
public class MyVisitor: ExpressionVisitor
{
private LambdaExpression visitor;
public Expression Modify(Expression expression, LambdaExpression visitor)
{
this.visitor = visitor;
return Visit(expression);
}
protected override Expression VisitBinary(BinaryExpression b)
{
var binary = visitor.Body as BinaryExpression;
return Expression.MakeBinary(ExpressionType.AndAlso, b, binary, b.IsLiftedToNull, b.Method);
}
}
您的Filter()
方法可能看起来像这样
private Expression<Func<Entity.Modelos.Flux, bool>> Filter()
{
var dateStart = dtpDateStart.Value.Date;
var dateEnd = dtpDateEnd.Value.Date;
var description = txtDescription.Text;
Expression<Func<Entity.Modelos.Flux, bool>> expr = null;
expr = f => f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date;
if (description != String.Empty)
{
//add filter
Expression<Func<Entity.Modelos.Flux, bool>> other = f => f.Description == description;
var modifier = new MyVisitor();
expr = (Expression<Func<Entity.Modelos.Flux, bool>>)modifier.Modify((Expression)expr, (LambdaExpression)other);
}
return expr;
}
例子查看以下内容以获取更多信息
如何修改表达式树(c#和Visual Basic)
如果这只是您需求的演示,那么您可以使用System.Linq.Expressions
命名空间创建和修改Expression Trees
。
然而,在你的问题中,使用EF可能会更容易:
bool filterDescription = !String.IsNullOrEmpty( txtDescription.Text );
expr = f =>
(
( f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date )
&&
( !filterDescription || ... add filter ... )
)
;
或普通c#:
if ( String.IsNullOrEmpty( txtDescription.Text ) )
{
expr = f => f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date;
}
else
{
expr = f => f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date
&&
... add filter ...
;
}
好的,这里有一个关于如何嵌入lambda语句的示例。这不是你的例子,但给你:
Func<int, int, EventHandler> makeHandler =
(dx, dy) => (sender, e) => {
var btn = (Button) sender;
btn.Top += dy;
btn.Left += dx;
};
btnUp.Click += makeHandler(0, -1);
btnDown.Click += makeHandler(0, 1);
btnLeft.Click += makeHandler(-1, 0);
btnRight.Click += makeHandler(1, 0);
很简单。访问此链接
棘手的是调用OrderByAlias
-使用MakeGenericMethod
可能是一种方式,如上面的链接所示。
试试:
private Expression<Func<Entity.Modelos.Flux, bool>> Filter()
{
var dateStart = dtpDateStart.Value.Date;
var dateEnd = dtpDateEnd.Value.Date;
Func<Entity.Modelos.Flux, bool> expr = null;
expr = f => f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date;
if(txtDescription.Text != String.Empty)
{
expr = f => expr(f) && f.Title.Equals(txtDescription.Text); // ← Your additional filter
}
return f => expr(f);
}