예제 #1
0
        public Expression Process(ParameterExpression ctxExpression, Type parameterType)
        {
            var leftExpression = ctxExpression.EvaluateExpression(Left, false);

            leftExpression = leftExpression.AddToStringWithEnumType();
            if (Operator != Operator.IsNull && Operator != Operator.NotIsNull)
            {
                leftExpression = leftExpression.AddValueWithNullableNumberType();
            }
            var        leftSideType = leftExpression.Type;
            Expression rightExpression;

            if (RightSideIsExpression)
            {
                rightExpression = ctxExpression.EvaluateExpression(Right);
                rightExpression = rightExpression.AddToStringWithEnumType().AddValueWithNullableNumberType();
            }
            else
            {
                rightExpression = GetRightConstantExpression(leftSideType);
            }

            Expression generatedExpression;

            switch (Operator)
            {
            case Operator.Equals:
                generatedExpression = Expression.Equal(leftExpression, rightExpression);
                break;

            case Operator.NotEquals:
                generatedExpression = Expression.Not(Expression.Equal(leftExpression, rightExpression));
                break;

            case Operator.GreaterThan:
                generatedExpression = leftExpression.Type == typeof(DateTime)
                        ? Expression.MakeBinary(ExpressionType.GreaterThan, leftExpression, rightExpression)
                        : Expression.GreaterThan(leftExpression, rightExpression);
                break;

            case Operator.GreaterOrEqual:
                generatedExpression = leftExpression.Type == typeof(DateTime)
                        ? Expression.MakeBinary(ExpressionType.GreaterThanOrEqual, leftExpression, rightExpression)
                        : Expression.GreaterThanOrEqual(leftExpression, rightExpression);
                break;

            case Operator.LessThan:
                generatedExpression = leftExpression.Type == typeof(DateTime)
                        ? Expression.MakeBinary(ExpressionType.LessThan, leftExpression, rightExpression)
                        : Expression.LessThan(leftExpression, rightExpression);
                break;

            case Operator.LessOrEqual:
                generatedExpression = leftExpression.Type == typeof(DateTime)
                        ? Expression.MakeBinary(ExpressionType.LessThanOrEqual, leftExpression, rightExpression)
                        : Expression.LessThanOrEqual(leftExpression, rightExpression);
                break;

            case Operator.Contains:
                generatedExpression = new Contains(leftExpression, rightExpression).Create();
                break;

            case Operator.NotContains:
                generatedExpression = Expression.Not(new Contains(leftExpression, rightExpression).Create());
                break;

            case Operator.ContainsAll:
                generatedExpression = new ContainsAll(leftExpression, rightExpression).Create();
                break;

            case Operator.NotContainsAll:
                generatedExpression = Expression.Not(new ContainsAll(leftExpression, rightExpression).Create());
                break;

            case Operator.StartsWith:
                generatedExpression = new StartsWith(leftExpression, rightExpression).Create();
                break;

            case Operator.NotStartsWith:
                generatedExpression = Expression.Not(new StartsWith(leftExpression, rightExpression).Create());
                break;

            case Operator.In:
                generatedExpression = new In(leftExpression, rightExpression).Create();
                break;

            case Operator.NotIn:
                generatedExpression = Expression.Not(new In(leftExpression, rightExpression).Create());
                break;

            case Operator.AllIn:
                generatedExpression = new AllIn(leftExpression, rightExpression).Create();
                break;

            case Operator.NotAllIn:
                generatedExpression = Expression.Not(new AllIn(leftExpression, rightExpression).Create());
                break;

            case Operator.AnyIn:
                generatedExpression = new AnyIn(leftExpression, rightExpression).Create();
                break;

            case Operator.NotAnyIn:
                generatedExpression = Expression.Not(new AnyIn(leftExpression, rightExpression).Create());
                break;

            case Operator.IsNull:
                if (leftSideType.IsPrimitiveType() && Nullable.GetUnderlyingType(leftSideType) != null)
                {
                    rightExpression = Expression.Constant(null, leftSideType);
                }
                generatedExpression = Expression.Equal(leftExpression, rightExpression);
                break;

            case Operator.NotIsNull:
                if (leftSideType.IsPrimitiveType() && Nullable.GetUnderlyingType(leftSideType) != null)
                {
                    rightExpression = Expression.Constant(null, leftSideType);
                }
                generatedExpression = Expression.Not(Expression.Equal(leftExpression, rightExpression));
                break;

            case Operator.IsEmpty:
                generatedExpression = new IsEmpty(leftExpression, rightExpression).Create();
                break;

            case Operator.NotIsEmpty:
                generatedExpression = Expression.Not(new IsEmpty(leftExpression, rightExpression).Create());
                break;

            case Operator.DiffWithinPct:
                generatedExpression = new DiffWithinPct(leftExpression, rightExpression, OperatorArgs).Create();
                break;

            case Operator.AllInRangePct:
                generatedExpression = new AllInRange(leftExpression, rightExpression, OperatorArgs).Create();
                break;

            default:
                throw new NotSupportedException($"operation {Operator} is not supported");
            }

            if (Operator == Operator.IsNull || Operator == Operator.NotIsNull)
            {
                return(generatedExpression);
            }

            return(leftExpression.AddNotNullCheck(out var nullCheckExpression)
                ? Expression.AndAlso(nullCheckExpression, generatedExpression)
                : generatedExpression);
        }