protected HqlTreeNode VisitConditionalExpression(ConditionalExpression expression)
        {
            var test    = VisitExpression(expression.Test).AsExpression();
            var ifTrue  = BooleanToCaseConvertor.ConvertBooleanToCase(VisitExpression(expression.IfTrue).AsExpression());
            var ifFalse = (expression.IfFalse != null
                                                           ? BooleanToCaseConvertor.ConvertBooleanToCase(VisitExpression(expression.IfFalse).AsExpression())
                                                           : null);

            var @case = _hqlTreeBuilder.Case(new[] { _hqlTreeBuilder.When(test, ifTrue) }, ifFalse);

            return((expression.Type == typeof(bool) || expression.Type == (typeof(bool?)))
                                           ? (HqlTreeNode)_hqlTreeBuilder.Equality(@case, _hqlTreeBuilder.True())
                                           : _hqlTreeBuilder.Cast(@case, expression.Type));
        }
Esempio n. 2
0
        public void Visit(Expression expression)
        {
            var distinct = expression as NhDistinctExpression;

            if (distinct != null)
            {
                expression = distinct.Expression;
            }

            // Find the sub trees that can be expressed purely in HQL
            var nominator = new SelectClauseHqlNominator(_parameters);

            nominator.Visit(expression);
            _hqlNodes.UnionWith(nominator.HqlCandidates);

            // Linq2SQL ignores calls to local methods. Linq2EF seems to not support
            // calls to local methods at all. For NHibernate we support local methods,
            // but prevent their use together with server-side distinct, since it may
            // end up being wrong.
            if (distinct != null && nominator.ContainsUntranslatedMethodCalls)
            {
                throw new NotSupportedException("Cannot use distinct on result that depends on methods for which no SQL equivalent exist.");
            }

            // Now visit the tree
            var projection = VisitExpression(expression);

            if ((projection != expression) && !_hqlNodes.Contains(expression))
            {
                ProjectionExpression = Expression.Lambda(projection, _inputParameter);
            }

            // Handle any boolean results in the output nodes
            _hqlTreeNodes = BooleanToCaseConvertor.Convert(_hqlTreeNodes).ToList();

            if (distinct != null)
            {
                var treeNodes = new List <HqlTreeNode>(_hqlTreeNodes.Count + 1)
                {
                    _hqlTreeBuilder.Distinct()
                };
                treeNodes.AddRange(_hqlTreeNodes);
                _hqlTreeNodes = new List <HqlExpression>(1)
                {
                    _hqlTreeBuilder.ExpressionSubTreeHolder(treeNodes)
                };
            }
        }
Esempio n. 3
0
        public void Visit(Expression expression)
        {
            // First, find the sub trees that can be expressed purely in HQL
            _hqlNodes = new Nominator(CanBeEvaluatedInHqlSelectStatement, CanBeEvaluatedInHqlStatementShortcut).Nominate(expression);

            // Now visit the tree
            Expression projection = VisitExpression(expression);

            if ((projection != expression) && !_hqlNodes.Contains(expression))
            {
                ProjectionExpression = Expression.Lambda(projection, _inputParameter);
            }

            // Finally, handle any boolean results in the output nodes
            _hqlTreeNodes = BooleanToCaseConvertor.Convert(_hqlTreeNodes).ToList();
        }