ComplianceServer/oldcode/Core.BLL/DynamicLinqExpressions.cs

123 lines
5.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}