73 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			73 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C#
		
	
	
	
| 
								 | 
							
								using System.Linq.Expressions;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								namespace langguanApi.Extensions
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    /// <summary>
							 | 
						|||
| 
								 | 
							
								    /// linq extension
							 | 
						|||
| 
								 | 
							
								    /// </summary>
							 | 
						|||
| 
								 | 
							
								    public static class WhereIfExtension
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        public static IQueryable<T> WhereIf<T>(this IQueryable<T> source, bool condition, Expression<Func<T, bool>> predicate)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return condition ? source.Where(predicate) : source;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        public static IQueryable<T> WhereIf<T>(this IQueryable<T> source, Expression<Func<T, int, bool>> predicate, bool condition)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return condition ? source.Where(predicate) : source;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, bool condition, Func<T, bool> predicate)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return condition ? source.Where(predicate) : source;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        public static Expression<Func<T, bool>> And<T>(
							 | 
						|||
| 
								 | 
							
								        this Expression<Func<T, bool>> first,
							 | 
						|||
| 
								 | 
							
								        Expression<Func<T, bool>> second)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return first.AndAlso<T>(second, Expression.AndAlso);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// 合并表达式以及参数
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <typeparam name="T"></typeparam>
							 | 
						|||
| 
								 | 
							
								        /// <param name="expr1"></param>
							 | 
						|||
| 
								 | 
							
								        /// <param name="expr2"></param>
							 | 
						|||
| 
								 | 
							
								        /// <param name="func"></param>
							 | 
						|||
| 
								 | 
							
								        /// <returns></returns>
							 | 
						|||
| 
								 | 
							
								        private static Expression<Func<T, bool>> AndAlso<T>(
							 | 
						|||
| 
								 | 
							
								        this Expression<Func<T, bool>> expr1,
							 | 
						|||
| 
								 | 
							
								        Expression<Func<T, bool>> expr2,
							 | 
						|||
| 
								 | 
							
								        Func<Expression, Expression, BinaryExpression> func)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            var parameter = Expression.Parameter(typeof(T));
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
							 | 
						|||
| 
								 | 
							
								            var left = leftVisitor.Visit(expr1.Body);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
							 | 
						|||
| 
								 | 
							
								            var right = rightVisitor.Visit(expr2.Body);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            return Expression.Lambda<Func<T, bool>>(
							 | 
						|||
| 
								 | 
							
								                func(left, right), parameter);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        private class ReplaceExpressionVisitor
							 | 
						|||
| 
								 | 
							
								: ExpressionVisitor
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            private readonly Expression _oldValue;
							 | 
						|||
| 
								 | 
							
								            private readonly Expression _newValue;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                _oldValue = oldValue;
							 | 
						|||
| 
								 | 
							
								                _newValue = newValue;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            public override Expression Visit(Expression node)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                if (node == _oldValue)
							 | 
						|||
| 
								 | 
							
								                    return _newValue;
							 | 
						|||
| 
								 | 
							
								                return base.Visit(node);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |