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)); }
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))); }
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) }; } }
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))); }