protected override Expression VisitMethodCall(MethodCallExpression node)
            {
                if (VisitorUtil.IsMappedAs(node.Method))
                {
                    var rawParameter = Visit(node.Arguments[0]);
                    var parameter    = rawParameter as ConstantExpression;
                    var type         = node.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 {node.Arguments[1]?.GetType().Name ?? "null"} instead.");
                    }

                    ConstantExpressions[parameter] = (IType)type.Value;

                    return(_removeMappedAsCalls
                                                ? rawParameter
                                                : node);
                }

                return(base.VisitMethodCall(node));
            }
        protected override Expression VisitMethodCallExpression(MethodCallExpression expression)
        {
            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 = VisitExpression(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.VisitMethodCallExpression(expression));
        }
 protected override Expression VisitMethodCallExpression(MethodCallExpression expression)
 {
     if (VisitorUtil.IsDynamicComponentDictionaryGetter(expression, _sessionFactory))
     {
         return(expression);
     }
     return(base.VisitMethodCallExpression(expression));
 }
示例#4
0
        protected override Expression VisitMethodCall(MethodCallExpression expression)
        {
            if (VisitorUtil.IsMappedAs(expression.Method))
            {
                var rawParameter = Visit(expression.Arguments[0]);
                // TODO 6.0: Remove below code and return expression as this logic is now inside ConstantTypeLocator
                var parameter = ParameterTypeLocator.UnwrapUnary(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(rawParameter);
            }

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

            if (PagingMethods.Contains(method) && !_sessionFactory.Dialect.SupportsVariableLimit)
            {
                var query = Visit(expression.Arguments[0]);
                //TODO 6.0: Remove the below code and return expression
                var arg = expression.Arguments[1];

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

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

            if (_functionRegistry != null &&
                _functionRegistry.TryGetGenerator(method, out var generator) &&
                generator.TryGetCollectionParameters(expression, out var collectionParameter))
            {
                _collectionParameters.Add(collectionParameter);
            }

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

            return(base.VisitMethodCall(expression));
        }
            protected override Expression VisitMethodCall(MethodCallExpression node)
            {
                if (VisitorUtil.IsMappedAs(node.Method))
                {
                    var rawParameter = Visit(node.Arguments[0]);
                    var parameter    = UnwrapUnary(rawParameter) as ConstantExpression;
                    var type         = node.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 {node.Arguments[1]?.GetType().Name ?? "null"} instead.");
                    }

                    ConstantExpressions[parameter] = (IType)type.Value;

                    return(_removeMappedAsCalls
                                                ? rawParameter
                                                : node);
                }

                if (EqualsGenerator.Methods.Contains(node.Method) || CompareGenerator.IsCompareMethod(node.Method))
                {
                    node = (MethodCallExpression)base.VisitMethodCall(node);
                    var left  = UnwrapUnary(node.Method.IsStatic ? node.Arguments[0] : node.Object);
                    var right = UnwrapUnary(node.Method.IsStatic ? node.Arguments[1] : node.Arguments[0]);
                    AddRelatedExpression(node, left, right);
                    AddRelatedExpression(node, right, left);

                    return(node);
                }

                // For hql method generators we do not want to guess the parameter type here, let hql logic figure it out.
                if (_functionRegistry.TryGetGenerator(node.Method, out _))
                {
                    var origHqlGenerator = _hqlGenerator;
                    _hqlGenerator = true;
                    var expression = base.VisitMethodCall(node);
                    _hqlGenerator = origHqlGenerator;
                    return(expression);
                }

                return(base.VisitMethodCall(node));
            }
        protected override Expression VisitMethodCallExpression(MethodCallExpression expression)
        {
            if (expression.Method.Name == nameof(LinqExtensionMethods.MappedAs) && expression.Method.DeclaringType == typeof(LinqExtensionMethods))
            {
                var rawParameter = VisitExpression(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 = VisitExpression(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.VisitMethodCallExpression(expression));
        }
示例#7
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))));
        }
        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);
        }
        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));
        }
示例#10
0
        private void FindNotNullMember(BinaryExpression binaryExpression, List <MemberExpression> notNullMembers)
        {
            _equalityNotNullMembers[binaryExpression] = notNullMembers;
            if (binaryExpression.NodeType != ExpressionType.NotEqual)
            {
                return;
            }

            MemberExpression memberExpression;

            if (VisitorUtil.IsNullConstant(binaryExpression.Right) && TryGetMemberAccess(binaryExpression.Left, out memberExpression))
            {
                notNullMembers.Add(memberExpression);
            }
            else if (VisitorUtil.IsNullConstant(binaryExpression.Left) && TryGetMemberAccess(binaryExpression.Right, out memberExpression))
            {
                notNullMembers.Add(memberExpression);
            }
        }
            private bool IsDynamicMember(Expression expression)
            {
                switch (expression)
                {
#if NETCOREAPP2_0
                case InvocationExpression invocationExpression:
                    // session.Query<Product>().Where("Properties.Name == @0", "First Product")
                    return(ExpressionsHelper.TryGetDynamicMemberBinder(invocationExpression, out _));
#endif
                case DynamicExpression dynamicExpression:
                    return(dynamicExpression.Binder is GetMemberBinder);

                case MethodCallExpression methodCallExpression:
                    // session.Query<Product>() where p.Properties["Name"] == "First Product" select p
                    return(VisitorUtil.TryGetPotentialDynamicComponentDictionaryMember(methodCallExpression, out _));

                default:
                    return(false);
                }
            }
示例#12
0
            protected override Expression VisitMethodCall(MethodCallExpression node)
            {
                if (VisitorUtil.IsMappedAs(node.Method))
                {
                    var rawParameter = Visit(node.Arguments[0]);
                    var parameter    = rawParameter as ConstantExpression;
                    var type         = node.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 {node.Arguments[1]?.GetType().Name ?? "null"} instead.");
                    }

                    ConstantExpressions[parameter] = (IType)type.Value;

                    return(_removeMappedAsCalls
                                                ? rawParameter
                                                : node);
                }

                if (EqualsGenerator.Methods.Contains(node.Method) || CompareGenerator.IsCompareMethod(node.Method))
                {
                    node = (MethodCallExpression)base.VisitMethodCall(node);
                    var left  = UnwrapUnary(node.Method.IsStatic ? node.Arguments[0] : node.Object);
                    var right = UnwrapUnary(node.Method.IsStatic ? node.Arguments[1] : node.Arguments[0]);
                    AddRelatedExpression(node, left, right);
                    AddRelatedExpression(node, right, left);

                    return(node);
                }

                return(base.VisitMethodCall(node));
            }
示例#13
0
        protected override Expression VisitMethodCallExpression(MethodCallExpression expression)
        {
            if (expression.Method.Name == "MappedAs" && expression.Method.DeclaringType == typeof(LinqExtensionMethods))
            {
                var parameter = (ConstantExpression)VisitExpression(expression.Arguments[0]);
                var type      = (ConstantExpression)expression.Arguments[1];

                _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 = VisitExpression(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.VisitMethodCallExpression(expression));
        }
        private HqlTreeNode TranslateEqualityComparison(BinaryExpression expression, HqlExpression lhs, HqlExpression rhs, Func <HqlExpression, HqlTreeNode> applyNullComparison, Func <HqlExpression, HqlExpression, HqlTreeNode> applyRegularComparison)
        {
            // Check for nulls on left or right.
            if (VisitorUtil.IsNullConstant(expression.Right))
            {
                rhs = null;
            }
            if (VisitorUtil.IsNullConstant(expression.Left))
            {
                lhs = null;
            }

            // Need to check for boolean equality
            if (lhs is HqlBooleanExpression || rhs is HqlBooleanExpression)
            {
                if (lhs != null)
                {
                    lhs = GetExpressionForBooleanEquality(expression.Left, lhs);
                }
                if (rhs != null)
                {
                    rhs = GetExpressionForBooleanEquality(expression.Right, rhs);
                }
            }

            if (lhs == null)
            {
                return(applyNullComparison(rhs));
            }
            if (rhs == null)
            {
                return(applyNullComparison(lhs));
            }

            return(applyRegularComparison(lhs, rhs));
        }
示例#15
0
        protected override Expression VisitBinaryExpression(BinaryExpression expression)
        {
            var result = base.VisitBinaryExpression(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);
        }
示例#16
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));
        }
示例#17
0
        public bool IsNullable(Expression expression, BinaryExpression equalityExpression)
        {
            switch (expression.NodeType)
            {
            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
            case ExpressionType.TypeAs:
                // a cast will not return null if the operand is not null (as long as TypeAs is not translated to
                // try_convert in SQL).
                return(IsNullable(((UnaryExpression)expression).Operand, equalityExpression));

            case ExpressionType.Not:
            case ExpressionType.And:
            case ExpressionType.Or:
            case ExpressionType.ExclusiveOr:
            case ExpressionType.LeftShift:
            case ExpressionType.RightShift:
            case ExpressionType.AndAlso:
            case ExpressionType.OrElse:
            case ExpressionType.Equal:
            case ExpressionType.NotEqual:
            case ExpressionType.GreaterThanOrEqual:
            case ExpressionType.GreaterThan:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
                return(false);

            case ExpressionType.Add:
            case ExpressionType.AddChecked:
            case ExpressionType.Divide:
            case ExpressionType.Modulo:
            case ExpressionType.Multiply:
            case ExpressionType.MultiplyChecked:
            case ExpressionType.Power:
            case ExpressionType.Subtract:
            case ExpressionType.SubtractChecked:
                var binaryExpression = (BinaryExpression)expression;
                return(IsNullable(binaryExpression.Left, equalityExpression) || IsNullable(binaryExpression.Right, equalityExpression));

            case ExpressionType.ArrayIndex:
                return(true);                        // for indexed lists we cannot determine whether the item will be null or not

            case ExpressionType.Coalesce:
                return(IsNullable(((BinaryExpression)expression).Right, equalityExpression));

            case ExpressionType.Conditional:
                var conditionalExpression = (ConditionalExpression)expression;
                return(IsNullable(conditionalExpression.IfTrue, equalityExpression) ||
                       IsNullable(conditionalExpression.IfFalse, equalityExpression));

            case ExpressionType.Call:
                var methodInfo = ((MethodCallExpression)expression).Method;
                return(!_functionRegistry.TryGetGenerator(methodInfo, out var method) || method.AllowsNullableReturnType(methodInfo));

            case ExpressionType.MemberAccess:
                return(IsNullable((MemberExpression)expression, equalityExpression));

            case ExpressionType.Extension:
                return(IsNullableExtension(expression, equalityExpression));

            case ExpressionType.TypeIs:                     // an equal or in operator will be generated and those cannot return null
            case ExpressionType.NewArrayInit:
                return(false);

            case ExpressionType.Constant:
                return(VisitorUtil.IsNullConstant(expression));

            case ExpressionType.Parameter:
                return(!expression.Type.IsValueType);

            default:
                return(true);
            }
        }