protected override Expression VisitMember(MemberExpression expression)
        {
            var isIdentifier = _isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name);

            if (isIdentifier)
            {
                _hasIdentifier = true;
            }
            if (!isIdentifier)
            {
                _memberExpressionDepth++;
            }

            var result = base.VisitMember(expression);

            if (!isIdentifier)
            {
                _memberExpressionDepth--;
            }

            if (_isEntityDecider.IsEntity(expression.Type) &&
                ((_requiresJoinForNonIdentifier && !_hasIdentifier) || _memberExpressionDepth > 0) &&
                _joiner.CanAddJoin(expression))
            {
                var key = ExpressionKeyVisitor.Visit(expression, null);
                return(_joiner.AddJoin(result, key));
            }

            _hasIdentifier = false;
            return(result);
        }
        protected override Expression VisitMemberExpression(MemberExpression expression)
        {
            var isIdentifier = _isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name);

            if (!isIdentifier)
            {
                _memberExpressionDepth++;
            }

            var result = base.VisitMemberExpression(expression);

            if (!isIdentifier)
            {
                _memberExpressionDepth--;
            }

            if (_isEntityDecider.IsEntity(expression.Type) &&
                _memberExpressionDepth > 0 &&
                _joiner.CanAddJoin(expression))
            {
                var key = ExpressionKeyVisitor.Visit(expression, null);
                return(_joiner.AddJoin(result, key));
            }

            return(result);
        }
Esempio n. 3
0
        // We would usually get NULL if one of our inner member expresions was null.
        // However, it's possible a method call will convert the null value from the failed join into a non-null value.
        // This could be optimized by actually checking what the method does.  For example StartsWith("s") would leave null as null and would still allow us to inner join.
        //protected override Expression VisitMethodCallExpression(MethodCallExpression expression)
        //{
        //    Expression result = base.VisitMethodCallExpression(expression);
        //    return result;
        //}

        protected override Expression VisitMemberExpression(MemberExpression expression)
        {
            // The member expression we're visiting might be on the end of a variety of things, such as:
            //   a.B
            //   a.B.C
            //   (a.B ?? a.C).D
            // I'm not sure what processing re-linq does to strange member expressions.
            // TODO: I suspect this code doesn't add the right joins for the last case.

            _memberExpressionDepth++;
            var result = base.VisitMemberExpression(expression);

            _memberExpressionDepth--;

            ExpressionValues values = _values.Pop().Operation(pvs => pvs.MemberAccess(expression.Type));

            if (_isEntityDecider.IsEntity(expression.Type))
            {
                // Don't add joins for things like a.B == a.C where B and C are entities.
                // We only need to join B when there's something like a.B.D.
                // TODO: Add an exception for the Id property.
                if (_memberExpressionDepth > 0)
                {
                    AddJoin(expression);
                }

                string key = ExpressionKeyVisitor.Visit(expression, null);
                values.MemberExpressionValuesIfEmptyOuterJoined[key] = PossibleValueSet.CreateNull(expression.Type);
            }
            SetResultValues(values);

            return(result);
        }
        protected override Expression VisitMemberExpression(MemberExpression expression)
        {
            if (_isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name))
            {
                _hasIdentifier = true;
            }
            else if (_hasIdentifier)
            {
                _identifierMemberExpressionDepth++;
            }

            var result = base.VisitMemberExpression(expression);

            if (_hasIdentifier)
            {
                _identifierMemberExpressionDepth--;
            }

            if (_isEntityDecider.IsEntity(expression.Type) &&
                (!_hasIdentifier || _identifierMemberExpressionDepth > 0) &&
                _joiner.CanAddJoin(expression))
            {
                var key = ExpressionKeyVisitor.Visit(expression, null);
                return(_joiner.AddJoin(result, key));
            }

            _hasIdentifier = false;

            return(result);
        }
        public static string Visit(Expression expression, IDictionary <ConstantExpression, NamedParameter> parameters)
        {
            var visitor = new ExpressionKeyVisitor(parameters);

            visitor.VisitExpression(expression);

            return(visitor.ToString());
        }
Esempio n. 6
0
        /// <summary>
        /// Generates the key for the expression.
        /// </summary>
        /// <param name="rootExpression">The expression.</param>
        /// <param name="sessionFactory">The session factory.</param>
        /// <param name="parameters">Parameters found in <paramref name="rootExpression"/>.</param>
        /// <returns>The key for the expression.</returns>
        public static string Visit(
            Expression rootExpression,
            IDictionary <ConstantExpression, NamedParameter> parameters,
            ISessionFactoryImplementor sessionFactory)
        {
            var visitor = new ExpressionKeyVisitor(parameters, sessionFactory);

            visitor.Visit(rootExpression);

            return(visitor.ToString());
        }
        // We would usually get NULL if one of our inner member expressions was null.
        // However, it's possible a method call will convert the null value from the failed join into a non-null value.
        // This could be optimized by actually checking what the method does.  For example StartsWith("s") would leave null as null and would still allow us to inner join.
        //protected override Expression VisitMethodCall(MethodCallExpression expression)
        //{
        //    Expression result = base.VisitMethodCall(expression);
        //    return result;
        //}

        protected override Expression VisitMember(MemberExpression expression)
        {
            // The member expression we're visiting might be on the end of a variety of things, such as:
            //   a.B
            //   a.B.C
            //   (a.B ?? a.C).D
            // I'm not sure what processing re-linq does to strange member expressions.
            // TODO: I suspect this code doesn't add the right joins for the last case.

            // A static member expression such as DateTime.Now has a null Expression.
            if (expression.Expression == null)
            {
                // A static member call is never a join, and it is not an instance member access either: leave
                // the current value on stack, untouched.
                return(base.VisitMember(expression));
            }

            var isIdentifier = _isEntityDecider.IsIdentifier(
                expression.Expression.Type,
                expression.Member.Name);

            if (!isIdentifier)
            {
                _memberExpressionDepth++;
            }

            var result = base.VisitMember(expression);

            if (!isIdentifier)
            {
                _memberExpressionDepth--;
            }

            ExpressionValues values = _values.Pop().Operation(pvs => pvs.MemberAccess(expression.Type));

            if (_isEntityDecider.IsEntity(expression.Type))
            {
                // Don't add joins for things like a.B == a.C where B and C are entities.
                // We only need to join B when there's something like a.B.D.
                var key = ExpressionKeyVisitor.Visit(expression, null);
                if (_memberExpressionDepth > 0 &&
                    _joiner.CanAddJoin(expression))
                {
                    result = _joiner.AddJoin(result, key);
                }

                values.MemberExpressionValuesIfEmptyOuterJoined[key] = PossibleValueSet.CreateNull(expression.Type);
            }
            SetResultValues(values);

            return(result);
        }
Esempio n. 8
0
        private Expression AddJoin(MemberExpression expression)
        {
            string         key = ExpressionKeyVisitor.Visit(expression, null);
            LeftJoinClause join;

            if (!_joins.TryGetValue(key, out join))
            {
                join = new LeftJoinClause(_nameGenerator.GetNewName(), expression.Type, expression);
                _joins.Add(key, join);
            }

            return(new QuerySourceReferenceExpression(join));
        }
Esempio n. 9
0
        protected internal Expression AddJoin(MemberExpression expression)
        {
            string       key = ExpressionKeyVisitor.Visit(expression, null);
            NhJoinClause join;

            if (!_joins.TryGetValue(key, out join))
            {
                join = new NhJoinClause(_nameGenerator.GetNewName(), expression.Type, expression);
                _joins.Add(key, join);
            }

            QuerySourceReferenceExpression newExpr = new QuerySourceReferenceExpression(join);

            if (!_expressionMap.ContainsKey(expression))
            {
                _expressionMap.Add(expression, newExpr);
            }

            return(newExpr);
        }
Esempio n. 10
0
        protected override Expression VisitMember(MemberExpression expression)
        {
            // A static member expression such as DateTime.Now has a null Expression.
            if (expression.Expression == null)
            {
                // A static member call is never a join, and it is not an instance member access either.
                return(base.VisitMember(expression));
            }

            var isIdentifier = _isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name);

            if (isIdentifier)
            {
                _hasIdentifier = true;
            }
            if (!isIdentifier)
            {
                _memberExpressionDepth++;
            }

            var result = base.VisitMember(expression);

            if (!isIdentifier)
            {
                _memberExpressionDepth--;
            }

            if (_isEntityDecider.IsEntity(expression.Type) &&
                ((_requiresJoinForNonIdentifier && !_hasIdentifier) || _memberExpressionDepth > 0) &&
                _joiner.CanAddJoin(expression))
            {
                var key = ExpressionKeyVisitor.Visit(expression, null);
                return(_joiner.AddJoin(result, key));
            }

            _hasIdentifier = false;
            return(result);
        }
Esempio n. 11
0
        protected override Expression VisitMemberExpression(MemberExpression expression)
        {
            ArgumentUtility.CheckNotNull("expression", expression);

            Expression newExpression;

            try
            {
                _memberExpressionDepth++;
                newExpression = base.VisitExpression(expression.Expression);
            }
            finally
            {
                _memberExpressionDepth--;
            }
            bool isEntity = _isEntityDecider.IsEntity(expression.Type);

            if (isEntity)
            {
                // See (h) why we do not check for _memberExpressionDepth here!
                AddPossibility(ExpressionKeyVisitor.Visit(expression, null), N);
            }

            if (_memberExpressionDepth > 0 && isEntity)
            {
                return(AddJoin(expression));
            }
            else
            {
                if (newExpression != expression.Expression)
                {
                    return(Expression.MakeMemberAccess(newExpression, expression.Member));
                }
                return(expression);
            }
        }