public NhLinqExpression(Expression expression, ISessionFactoryImplementor sessionFactory)
        {
            _expression = NhPartialEvaluatingExpressionTreeVisitor.EvaluateIndependentSubtrees(expression);

            // We want logging to be as close as possible to the original expression sent from the
            // application. But if we log before partial evaluation, the log won't include e.g.
            // subquery expressions if those are defined by the application in a variable referenced
            // from the main query.
            LinqLogging.LogExpression("Expression (partially evaluated)", _expression);

            _constantToParameterMap = ExpressionParameterVisitor.Visit(_expression, sessionFactory);

            ParameterValuesByName = _constantToParameterMap.Values.ToDictionary(p => p.Name,
                                                                                p => System.Tuple.Create(p.Value, p.Type));

            Key = ExpressionKeyVisitor.Visit(_expression, _constantToParameterMap);

            Type = _expression.Type;

            // Note - re-linq handles return types via the GetOutputDataInfo method, and allows for SingleOrDefault here for the ChoiceResultOperator...
            ReturnType = NhLinqExpressionReturnType.Scalar;

            if (typeof(IQueryable).IsAssignableFrom(Type))
            {
                Type       = Type.GetGenericArguments()[0];
                ReturnType = NhLinqExpressionReturnType.Sequence;
            }
        }
        public NhLinqExpression(Expression expression, ISessionFactoryImplementor sessionFactory)
        {
            _expression = NhPartialEvaluatingExpressionTreeVisitor.EvaluateIndependentSubtrees(expression);

            _constantToParameterMap = ExpressionParameterVisitor.Visit(_expression, sessionFactory);

            ParameterValuesByName = _constantToParameterMap.Values.ToDictionary(p => p.Name,
                                                                                p =>
                                                                                new Tuple <object, IType> {
                First = p.Value, Second = p.Type
            });

            Key = ExpressionKeyVisitor.Visit(_expression, _constantToParameterMap);

            Type = _expression.Type;

            // Note - re-linq handles return types via the GetOutputDataInfo method, and allows for SingleOrDefault here for the ChoiceResultOperator...
            ReturnType = NhLinqExpressionReturnType.Scalar;

            if (typeof(IQueryable).IsAssignableFrom(Type))
            {
                Type       = Type.GetGenericArguments()[0];
                ReturnType = NhLinqExpressionReturnType.Sequence;
            }
        }
        /// <summary>
        /// Applies the minimal transformations required before parameterization,
        /// expression key computing and parsing.
        /// </summary>
        /// <param name="expression">The expression to transform.</param>
        /// <returns>The transformed expression.</returns>
        public static Expression PreTransform(Expression expression)
        {
            var partiallyEvaluatedExpression = NhPartialEvaluatingExpressionTreeVisitor.EvaluateIndependentSubtrees(expression);

            return(PreProcessor.Process(partiallyEvaluatedExpression));
        }