107 lines
4.2 KiB
C#
107 lines
4.2 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Linq.Expressions;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace DG.Core
|
||
{
|
||
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.OrElse(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]);
|
||
|
||
var param = Expression.Parameter(typeof(T), "x");
|
||
Expression body = Expression.Invoke(predicates[0], param);
|
||
for (int i = 1; i < predicates.Length; i++)
|
||
{
|
||
body = Expression.OrElse(body, Expression.Invoke(predicates[i], param));
|
||
}
|
||
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
|
||
return source.Where(lambda);
|
||
}
|
||
}
|
||
|
||
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;
|
||
}
|
||
}
|
||
}
|