Exemplo n.º 1
0
        private HqlTreeNode BuildFromArray(Array valueArray, HqlTreeBuilder treeBuilder)
        {
            var elementType = valueArray.GetType().GetElementType();

            if (!elementType.IsValueType && elementType != typeof(string))
            {
                throw new ArgumentException("Only primitives and strings can be used");
            }

            Type enumUnderlyingType = elementType.IsEnum ? Enum.GetUnderlyingType(elementType) : null;
            var  variants           = new HqlExpression[valueArray.Length];

            for (int index = 0; index < valueArray.Length; index++)
            {
                var variant = valueArray.GetValue(index);
                var val     = variant;

                if (elementType.IsEnum)
                {
                    val = Convert.ChangeType(variant, enumUnderlyingType);
                }

                variants[index] = treeBuilder.Constant(val);
            }

            return(treeBuilder.ExpressionSubTreeHolder(variants));
        }
Exemplo n.º 2
0
        internal HqlBooleanExpression BuildOfType(Expression expression, System.Type type)
        {
            var sessionFactory = _parameters.SessionFactory;
            var meta           = sessionFactory.GetClassMetadata(type) as Persister.Entity.AbstractEntityPersister;

            if (meta != null && !meta.IsExplicitPolymorphism)
            {
                //Adapted the logic found in SingleTableEntityPersister.DiscriminatorFilterFragment
                var nodes = meta
                            .SubclassClosure
                            .Select(typeName => (NHibernate.Persister.Entity.IQueryable)sessionFactory.GetEntityPersister(typeName))
                            .Where(persister => !persister.IsAbstract)
                            .Select(persister => _hqlTreeBuilder.Ident(persister.EntityName))
                            .ToList();

                if (nodes.Count == 1)
                {
                    return(_hqlTreeBuilder.Equality(
                               _hqlTreeBuilder.Dot(Visit(expression).AsExpression(), _hqlTreeBuilder.Class()),
                               nodes[0]));
                }

                if (nodes.Count > 1)
                {
                    return(_hqlTreeBuilder.In(
                               _hqlTreeBuilder.Dot(
                                   Visit(expression).AsExpression(),
                                   _hqlTreeBuilder.Class()),
                               _hqlTreeBuilder.ExpressionSubTreeHolder(nodes)));
                }

                if (nodes.Count == 0)
                {
                    const string abstractClassWithNoSubclassExceptionMessageTemplate =
                        @"The class {0} can't be instatiated and does not have mapped subclasses; 
possible solutions:
- don't map the abstract class
- map its subclasses.";

                    throw new NotSupportedException(string.Format(abstractClassWithNoSubclassExceptionMessageTemplate, meta.EntityName));
                }
            }

            return(_hqlTreeBuilder.Equality(
                       _hqlTreeBuilder.Dot(Visit(expression).AsExpression(), _hqlTreeBuilder.Class()),
                       _hqlTreeBuilder.Ident(type.FullName)));
        }
Exemplo n.º 3
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)
                };
            }
        }
Exemplo n.º 4
0
        private HqlTreeNode BuildFromArray(IEnumerable valueArray, HqlTreeBuilder treeBuilder, Type elementType)
        {
            Type enumUnderlyingType      = elementType.IsEnum ? Enum.GetUnderlyingType(elementType) : null;
            IList <HqlTreeNode> variants = new List <HqlTreeNode>();

            foreach (object variant in valueArray)
            {
                object val = variant;

                if (elementType.IsEnum)
                {
                    val = Convert.ChangeType(variant, enumUnderlyingType);
                }

                HqlConstant hqlConstant = treeBuilder.Constant(val);
                variants.Add(hqlConstant);
            }

            return(treeBuilder.ExpressionSubTreeHolder(variants));
        }
        protected HqlTreeNode VisitNhDistinct(NhDistinctExpression expression)
        {
            var visitor = new HqlGeneratorExpressionTreeVisitor(_parameters);

            return(_hqlTreeBuilder.ExpressionSubTreeHolder(_hqlTreeBuilder.Distinct(), visitor.VisitExpression(expression.Expression)));
        }