8,492
社区成员
发帖
与我相关
我的任务
分享
var innerChild = PredicateBuilder.True<表对应的实体类>();
innerChild = innerChild.And(p => p.字段a== 参数1);
if (!string.IsNullOrEmpty(参数2))
{
innerChild = innerChild.And(p => p.字段b.Contains(参数2));
}
if (!string.IsNullOrEmpty(参数3))
{
innerChild = innerChild.And(p => p.字段c== Convert.ToDateTime(参数3));
}
//然后把innerChild作为where条件传进去。
//界面上多个条件,没办法,必须得判断,不过一个界面上怎么可能100多个文本框给用户查询呢?
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T> () { return f => true; }
public static Expression<Func<T, bool>> False<T> () { return f => false; }
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
}
public static class ExpressionBuilder
{
private static MethodInfo containsMethod = typeof(string).GetMethod("Contains" );
private static MethodInfo startsWithMethod =
typeof(string).GetMethod("StartsWith", new Type [] {typeof(string)});
private static MethodInfo endsWithMethod =
typeof(string).GetMethod("EndsWith", new Type [] { typeof(string)});
public static Expression<Func<T,
bool >> GetExpression<T>(IList<Filter> filters)
{
if (filters.Count == 0)
return null ;
ParameterExpression param = Expression.Parameter(typeof (T), "t" );
Expression exp = null ;
if (filters.Count == 1)
exp = GetExpression<T>(param, filters[0]);
else if (filters.Count == 2)
exp = GetExpression<T>(param, filters[0], filters[1]);
else
{
while (filters.Count > 0)
{
var f1 = filters[0];
var f2 = filters[1];
if (exp == null )
exp = GetExpression<T>(param, filters[0], filters[1]);
else
exp = Expression.AndAlso(exp, GetExpression<T>(param, filters[0], filters[1]));
filters.Remove(f1);
filters.Remove(f2);
if (filters.Count == 1)
{
exp = Expression .AndAlso(exp, GetExpression<T>(param, filters[0]));
filters.RemoveAt(0);
}
}
}
return Expression.Lambda<Func<T, bool>>(exp, param);
}
private static Expression GetExpression<T>(ParameterExpression param, Filter filter)
{
MemberExpression member = Expression.Property(param, filter.PropertyName);
ConstantExpression constant = Expression.Constant(filter.Value);
switch (filter.Operation)
{
case Op.Equals:
return Expression.Equal(member, constant);
case Op.GreaterThan:
return Expression.GreaterThan(member, constant);
case Op.GreaterThanOrEqual:
return Expression.GreaterThanOrEqual(member, constant);
case Op.LessThan:
return Expression.LessThan(member, constant);
case Op.LessThanOrEqual:
return Expression.LessThanOrEqual(member, constant);
case Op.Contains:
return Expression.Call(member, containsMethod, constant);
case Op.StartsWith:
return Expression.Call(member, startsWithMethod, constant);
case Op.EndsWith:
return Expression.Call(member, endsWithMethod, constant);
}
return null ;
}
private static BinaryExpression GetExpression<T>
(ParameterExpression param, Filter filter1, Filter filter2)
{
Expression bin1 = GetExpression<T>(param, filter1);
Expression bin2 = GetExpression<T>(param, filter2);
return Expression.AndAlso(bin1, bin2);
}
}
public class Filter
{
public string PropertyName { get ; set ; }
public Op Operation { get ; set ; }
public object Value { get ; set ; }
}
public enum Op
{
Equals,
GreaterThan,
LessThan,
GreaterThanOrEqual,
LessThanOrEqual,
Contains,
StartsWith,
EndsWith
}
// 调用
List<Filter> filter = new List<Filter>()
{
new Filter { PropertyName = "City" ,
Operation = Op .Equals, Value = "Mitrovice" },
new Filter { PropertyName = "Name" ,
Operation = Op .StartsWith, Value = "L" },
new Filter { PropertyName = "Salary" ,
Operation = Op .GreaterThan, Value = 9000.0 }
};
var deleg = ExpressionBuilder.GetExpression<Person>(filter).Compile();
var filteredCollection = persons.Where(deleg).ToList();