コード例 #1
0
        private HqlTreeNode TranslateEqualityComparison(BinaryExpression expression)
        {
            var lhs = VisitExpression(expression.Left).ToArithmeticExpression();
            var rhs = VisitExpression(expression.Right).ToArithmeticExpression();

            // Check for nulls on left or right.
            if (VisitorUtil.IsNullConstant(expression.Right))
            {
                rhs = null;
            }

            if (VisitorUtil.IsNullConstant(expression.Left))
            {
                lhs = null;
            }

            if (lhs == null && rhs == null)
            {
                return(_hqlTreeBuilder.True());
            }

            if (lhs == null)
            {
                return(_hqlTreeBuilder.IsNull(rhs));
            }

            if (rhs == null)
            {
                return(_hqlTreeBuilder.IsNull((lhs)));
            }

            var lhsNullable = IsNullable(lhs);
            var rhsNullable = IsNullable(rhs);

            var equality = _hqlTreeBuilder.Equality(lhs, rhs);

            if (!lhsNullable || !rhsNullable)
            {
                return(equality);
            }

            var lhs2 = VisitExpression(expression.Left).ToArithmeticExpression();
            var rhs2 = VisitExpression(expression.Right).ToArithmeticExpression();

            return(_hqlTreeBuilder.BooleanOr(
                       equality,
                       _hqlTreeBuilder.BooleanAnd(
                           _hqlTreeBuilder.IsNull(lhs2),
                           _hqlTreeBuilder.IsNull(rhs2))));
        }
コード例 #2
0
        protected override Expression VisitMethodCall(MethodCallExpression expression)
        {
            if (expression.Method.Name == nameof(LinqExtensionMethods.MappedAs) && expression.Method.DeclaringType == typeof(LinqExtensionMethods))
            {
                var rawParameter = Visit(expression.Arguments[0]);
                var parameter    = rawParameter as ConstantExpression;
                var type         = expression.Arguments[1] as ConstantExpression;
                if (parameter == null)
                {
                    throw new HibernateException(
                              $"{nameof(LinqExtensionMethods.MappedAs)} must be called on an expression which can be evaluated as " +
                              $"{nameof(ConstantExpression)}. It was call on {rawParameter?.GetType().Name ?? "null"} instead.");
                }
                if (type == null)
                {
                    throw new HibernateException(
                              $"{nameof(LinqExtensionMethods.MappedAs)} type must be supplied as {nameof(ConstantExpression)}. " +
                              $"It was {expression.Arguments[1]?.GetType().Name ?? "null"} instead.");
                }

                _parameters[parameter].Type = (IType)type.Value;

                return(parameter);
            }

            var method = expression.Method.IsGenericMethod
                                                         ? expression.Method.GetGenericMethodDefinition()
                                                         : expression.Method;

            if (_pagingMethods.Contains(method) && !_sessionFactory.Dialect.SupportsVariableLimit)
            {
                //TODO: find a way to make this code cleaner
                var query = Visit(expression.Arguments[0]);
                var arg   = expression.Arguments[1];

                if (query == expression.Arguments[0])
                {
                    return(expression);
                }

                return(Expression.Call(null, expression.Method, query, arg));
            }

            if (VisitorUtil.IsDynamicComponentDictionaryGetter(expression, _sessionFactory))
            {
                return(expression);
            }

            return(base.VisitMethodCall(expression));
        }
コード例 #3
0
        private static bool IsConstructionToNullComparison(Expression expression)
        {
            var testExpression = expression as BinaryExpression;

            if (testExpression != null)
            {
                if ((IsConstruction(testExpression.Left) && VisitorUtil.IsNullConstant(testExpression.Right)) ||
                    (IsConstruction(testExpression.Right) && VisitorUtil.IsNullConstant(testExpression.Left)))
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #4
0
        protected override Expression VisitConditional(ConditionalExpression expression)
        {
            var testExpression = Visit(expression.Test);

            bool testExprResult;

            if (VisitorUtil.IsBooleanConstant(testExpression, out testExprResult))
            {
                if (testExprResult)
                {
                    return(Visit(expression.IfTrue));
                }

                return(Visit(expression.IfFalse));
            }

            return(base.VisitConditional(expression));
        }
コード例 #5
0
        protected override Expression VisitBinary(BinaryExpression expression)
        {
            var result = base.VisitBinary(expression);

            if (expression.NodeType == ExpressionType.AndAlso)
            {
                HandleBinaryOperation((a, b) => a.AndAlso(b));
            }
            else if (expression.NodeType == ExpressionType.OrElse)
            {
                HandleBinaryOperation((a, b) => a.OrElse(b));
            }
            else if (expression.NodeType == ExpressionType.NotEqual && VisitorUtil.IsNullConstant(expression.Right))
            {
                // Discard result from right null.  Left is visited first, so it's below right on the stack.
                _values.Pop();

                HandleUnaryOperation(pvs => pvs.IsNotNull());
            }
            else if (expression.NodeType == ExpressionType.NotEqual && VisitorUtil.IsNullConstant(expression.Left))
            {
                // Discard result from left null.
                var right = _values.Pop();
                _values.Pop();                 // Discard left.
                _values.Push(right);

                HandleUnaryOperation(pvs => pvs.IsNotNull());
            }
            else if (expression.NodeType == ExpressionType.Equal && VisitorUtil.IsNullConstant(expression.Right))
            {
                // Discard result from right null.  Left is visited first, so it's below right on the stack.
                _values.Pop();

                HandleUnaryOperation(pvs => pvs.IsNull());
            }
            else if (expression.NodeType == ExpressionType.Equal && VisitorUtil.IsNullConstant(expression.Left))
            {
                // Discard result from left null.
                var right = _values.Pop();
                _values.Pop();                 // Discard left.
                _values.Push(right);

                HandleUnaryOperation(pvs => pvs.IsNull());
            }
            else if (expression.NodeType == ExpressionType.Coalesce)
            {
                HandleBinaryOperation((a, b) => a.Coalesce(b));
            }
            else if (expression.NodeType == ExpressionType.Add || expression.NodeType == ExpressionType.AddChecked)
            {
                HandleBinaryOperation((a, b) => a.Add(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.Divide)
            {
                HandleBinaryOperation((a, b) => a.Divide(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.Modulo)
            {
                HandleBinaryOperation((a, b) => a.Modulo(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.Multiply || expression.NodeType == ExpressionType.MultiplyChecked)
            {
                HandleBinaryOperation((a, b) => a.Multiply(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.Power)
            {
                HandleBinaryOperation((a, b) => a.Power(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.Subtract || expression.NodeType == ExpressionType.SubtractChecked)
            {
                HandleBinaryOperation((a, b) => a.Subtract(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.And)
            {
                HandleBinaryOperation((a, b) => a.And(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.Or)
            {
                HandleBinaryOperation((a, b) => a.Or(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.ExclusiveOr)
            {
                HandleBinaryOperation((a, b) => a.ExclusiveOr(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.LeftShift)
            {
                HandleBinaryOperation((a, b) => a.LeftShift(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.RightShift)
            {
                HandleBinaryOperation((a, b) => a.RightShift(b, expression.Type));
            }
            else if (expression.NodeType == ExpressionType.Equal)
            {
                HandleBinaryOperation((a, b) => a.Equal(b));
            }
            else if (expression.NodeType == ExpressionType.NotEqual)
            {
                HandleBinaryOperation((a, b) => a.NotEqual(b));
            }
            else if (expression.NodeType == ExpressionType.GreaterThanOrEqual)
            {
                HandleBinaryOperation((a, b) => a.GreaterThanOrEqual(b));
            }
            else if (expression.NodeType == ExpressionType.GreaterThan)
            {
                HandleBinaryOperation((a, b) => a.GreaterThan(b));
            }
            else if (expression.NodeType == ExpressionType.LessThan)
            {
                HandleBinaryOperation((a, b) => a.LessThan(b));
            }
            else if (expression.NodeType == ExpressionType.LessThanOrEqual)
            {
                HandleBinaryOperation((a, b) => a.LessThanOrEqual(b));
            }

            return(result);
        }
コード例 #6
0
        private HqlTreeNode TranslateInequalityComparison(BinaryExpression expression)
        {
            var lhs = VisitExpression(expression.Left).ToArithmeticExpression();
            var rhs = VisitExpression(expression.Right).ToArithmeticExpression();

            // Check for nulls on left or right.
            if (VisitorUtil.IsNullConstant(expression.Right))
            {
                rhs = null;
            }
            if (VisitorUtil.IsNullConstant(expression.Left))
            {
                lhs = null;
            }

            if (lhs == null && rhs == null)
            {
                return(_hqlTreeBuilder.False());
            }

            if (lhs == null)
            {
                return(_hqlTreeBuilder.IsNotNull(rhs));
            }

            if (rhs == null)
            {
                return(_hqlTreeBuilder.IsNotNull(lhs));
            }

            var lhsNullable = IsNullable(lhs);
            var rhsNullable = IsNullable(rhs);

            var inequality = _hqlTreeBuilder.Inequality(lhs, rhs);

            if (!lhsNullable && !rhsNullable)
            {
                return(inequality);
            }

            var lhs2 = VisitExpression(expression.Left).ToArithmeticExpression();
            var rhs2 = VisitExpression(expression.Right).ToArithmeticExpression();

            HqlBooleanExpression booleanExpression;

            if (lhsNullable && rhsNullable)
            {
                booleanExpression = _hqlTreeBuilder.Inequality(
                    _hqlTreeBuilder.IsNull(lhs2).ToArithmeticExpression(),
                    _hqlTreeBuilder.IsNull(rhs2).ToArithmeticExpression());
            }
            else if (lhsNullable)
            {
                booleanExpression = _hqlTreeBuilder.IsNull(lhs2);
            }
            else
            {
                booleanExpression = _hqlTreeBuilder.IsNull(rhs2);
            }

            return(_hqlTreeBuilder.BooleanOr(inequality, booleanExpression));
        }