123 lines
5.0 KiB
C#
123 lines
5.0 KiB
C#
using System;
|
||
using System.Linq;
|
||
using System.Linq.Expressions;
|
||
|
||
namespace CRM.Core.BLL
|
||
{
|
||
public static class PredicateExtensionses
|
||
{
|
||
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>> And<T>(this Expression<Func<T, bool>> expLeft, Expression<Func<T, bool>> expRight)
|
||
{
|
||
var candidateExpr = Expression.Parameter(typeof(T), "candidate");
|
||
var parameterReplacer = new ParameterReplacer(candidateExpr);
|
||
|
||
var left = parameterReplacer.Replace(expLeft.Body);
|
||
var right = parameterReplacer.Replace(expRight.Body);
|
||
var body = Expression.And(left, right);
|
||
|
||
return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
|
||
}
|
||
|
||
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expLeft, Expression<Func<T, bool>> expRight)
|
||
{
|
||
var candidateExpr = Expression.Parameter(typeof(T), "candidate");
|
||
var parameterReplacer = new ParameterReplacer(candidateExpr);
|
||
|
||
var left = parameterReplacer.Replace(expLeft.Body);
|
||
var right = parameterReplacer.Replace(expRight.Body);
|
||
var body = Expression.Or(left, right);
|
||
|
||
return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
|
||
}
|
||
/// <summary>
|
||
/// And ((a or b )and (x or d))关系,但是and后面里面的关系是Or的关系,如 a.resid='' and ((a.channel>=1 and a.channel<10) or (a.channel>=50 and a.channel<60))
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="expLeft"></param>
|
||
/// <param name="expRight"></param>
|
||
/// <returns></returns>
|
||
public static Expression<Func<T, bool>> AndListOr<T>(this Expression<Func<T, bool>> expLeft, Expression<Func<T, bool>>[] predicates)
|
||
{
|
||
var candidateExpr = Expression.Parameter(typeof(T), "candidate");
|
||
var parameterReplacer = new ParameterReplacer(candidateExpr);
|
||
var left = parameterReplacer.Replace(expLeft.Body);
|
||
Expression<Func<T, bool>> lambda = predicates[0];
|
||
for (int i = 1; i < predicates.Length; i++)
|
||
{
|
||
lambda = lambda.Or(predicates[i]);
|
||
}
|
||
var right = parameterReplacer.Replace(lambda.Body);
|
||
var body = Expression.And(left, right);
|
||
|
||
return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 传入条件之间为OR查询
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="source"></param>
|
||
/// <param name="predicates"></param>
|
||
/// <returns></returns>
|
||
public static IQueryable<T> WhereOR<T>(this IQueryable<T> source, params Expression<Func<T, bool>>[] predicates)
|
||
{
|
||
if (source == null) throw new ArgumentNullException("source");
|
||
if (predicates == null) throw new ArgumentNullException("predicates");
|
||
if (predicates.Length == 0) return source.Where(x => true);
|
||
if (predicates.Length == 1) return source.Where(predicates[0]);
|
||
|
||
Expression<Func<T, bool>> lambda = predicates[0];
|
||
for (int i = 1; i < predicates.Length; i++)
|
||
{
|
||
lambda = lambda.Or(predicates[i]);
|
||
}
|
||
return source.Where(lambda);
|
||
}
|
||
|
||
//public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
|
||
//{
|
||
// return ParameterRebinder.Compose(first, second, Expression.Or);
|
||
//}
|
||
}
|
||
|
||
//public class ParameterRebinder : ExpressionVisitor
|
||
//{
|
||
// public static Expression<T> Compose<T>(Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
|
||
// {
|
||
// // build parameter map (from parameters of second to parameters of first)
|
||
// var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
|
||
|
||
// // replace parameters in the second lambda expression with parameters from the first
|
||
// var secondBody = ReplaceParameters(map, second.Body);
|
||
|
||
// // apply composition of lambda expression bodies to parameters from the first expression
|
||
// return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
|
||
// }
|
||
|
||
//}
|
||
|
||
internal class ParameterReplacer : ExpressionVisitor
|
||
{
|
||
public ParameterReplacer(ParameterExpression paramExpr)
|
||
{
|
||
this.ParameterExpression = paramExpr;
|
||
}
|
||
|
||
public ParameterExpression ParameterExpression { get; private set; }
|
||
|
||
public Expression Replace(Expression expr)
|
||
{
|
||
return this.Visit(expr);
|
||
}
|
||
|
||
protected override Expression VisitParameter(ParameterExpression p)
|
||
{
|
||
return this.ParameterExpression;
|
||
}
|
||
}
|
||
}
|