123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Linq.Expressions;
- using VCommon.Collections;
- using static System.Linq.Expressions.Expression;
- namespace VCommon.Linq.Expressions.Predicate
- {
- public sealed class PredicateBuilder<T>
- {
- public static readonly PredicateBuilder<T> Instance = new PredicateBuilder<T>();
- private PredicateBuilder()
- {
- }
- public PredicateWrap<T> Custom(Expression<Func<T, bool>> expression) => expression;
- public PredicateWrap<T> In<TV>(Expression<Func<T, TV>> selector, IEnumerable<TV> checkIn)
- {
- if (checkIn == null) return null;
- var c = Constant(checkIn.WrapEnumerable());
- var p = selector.Parameters[0];
- var call = Call(typeof(Enumerable), "Contains", new[] { typeof(TV) }, c, selector.Body);
- var exp = Lambda<Func<T, bool>>(call, p);
- return exp;
- }
- public PredicateWrap<T> NotIn<TV>(Expression<Func<T, TV>> selector, IEnumerable<TV> checkIn)
- {
- if (checkIn == null) return null;
-
- var p = selector.Parameters[0];
- var values = Constant(checkIn.WrapEnumerable());
- var @in = Call(typeof(Enumerable), "Contains", new[] { typeof(TV) }, values, selector.Body);
- var not = Not(@in);
- var exp = Lambda<Func<T, bool>>(not, p);
- return exp;
- }
- public PredicateWrap<T> StringContains(Expression<Func<T, string>> selector, string contains)
- {
- if (string.IsNullOrWhiteSpace(contains)) return null;
- var stringContainsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) })
- ?? throw new SystemException("ILL SYSTEM LIB? string.Contains(string) NOT EXIST??");
- var parameterExp = selector.Parameters[0];
- var valExp = Constant(contains, typeof(string));
- var callExp = Call(selector.Body, stringContainsMethod, valExp);
- var lambda = Lambda<Func<T, bool>>(callExp, parameterExp);
- return lambda;
- }
- public PredicateWrap<T> Between<TV>(Expression<Func<T, TV>> selector, TV min, TV max, bool include = true)
- {
- if (null == min && null == max) return null;
- PredicateWrap<T> predicateWrap = null;
- if (null != min)
- {
- predicateWrap = include
- ? GreaterThanOrEqual(selector, min)
- : GreaterThan(selector, min);
- }
- if (null != max)
- {
- predicateWrap &= include
- ? LessThanOrEqual(selector, max)
- : LessThan(selector, max);
- }
- return predicateWrap;
- }
- public PredicateWrap<T> Equal<TV>(Expression<Func<T, TV>> selector, TV valueToCompare) => BinOp(Expression.Equal, selector, valueToCompare);
- public PredicateWrap<T> NotEqual<TV>(Expression<Func<T, TV>> selector, TV valueToCompare) => BinOp(Expression.NotEqual, selector, valueToCompare);
- public PredicateWrap<T> LessThan<TV>(Expression<Func<T, TV>> selector, TV valueToCompare) => BinOp(Expression.LessThan, selector, valueToCompare);
- public PredicateWrap<T> LessThanOrEqual<TV>(Expression<Func<T, TV>> selector, TV valueToCompare) => BinOp(Expression.LessThanOrEqual, selector, valueToCompare);
- public PredicateWrap<T> GreaterThan<TV>(Expression<Func<T, TV>> selector, TV valueToCompare) => BinOp(Expression.GreaterThan, selector, valueToCompare);
- public PredicateWrap<T> GreaterThanOrEqual<TV>(Expression<Func<T, TV>> selector, TV valueToCompare) => BinOp(Expression.GreaterThanOrEqual, selector, valueToCompare);
- private static PredicateWrap<T> BinOp<TV>(Func<Expression, Expression, Expression> op, Expression<Func<T, TV>> selector, TV valueToCompare)
- {
- var parameterExp = selector.Parameters[0];
- var valToCompareExp = Constant(valueToCompare, typeof(TV));
- var callExp = op(selector.Body, valToCompareExp);
- var lambda = Lambda<Func<T, bool>>(callExp, parameterExp);
- return lambda;
- }
- }
- }
|