Beispiel #1
0
        protected HqlTreeNode VisitNhDistinct(NhDistinctExpression expression)
        {
            var visitor = new HqlGeneratorExpressionTreeVisitor(_parameters);

            return(_hqlTreeBuilder.DistinctHolder(
                       _hqlTreeBuilder.Distinct(),
                       visitor.VisitExpression(expression.Expression)));
        }
Beispiel #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);

            expression = nominator.Visit(expression);
            _hqlNodes  = 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 = _hqlTreeNodes.ConvertAll(node => node.ToArithmeticExpression());

            if (distinct != null)
            {
                var treeNodes = new List <HqlTreeNode>(_hqlTreeNodes.Count + 1)
                {
                    _hqlTreeBuilder.Distinct()
                };
                treeNodes.AddRange(_hqlTreeNodes);
                _hqlTreeNodes = new List <HqlExpression>(1)
                {
                    _hqlTreeBuilder.ExpressionSubTreeHolder(treeNodes)
                };
            }
        }