/// <summary>
            /// Constructs a join propagator.
            /// </summary>
            /// <param name="left">Result of propagating changes in the left input to the join</param>
            /// <param name="right">Result of propagating changes in the right input to the join</param>
            /// <param name="node">Join operator in update mapping view over which to propagate changes</param>
            /// <param name="parent">Handler of propagation for the entire update mapping view</param>
            internal JoinPropagator(ChangeNode left, ChangeNode right, DbJoinExpression node, Propagator parent)
            {
                EntityUtil.CheckArgumentNull(left, "left");
                EntityUtil.CheckArgumentNull(right, "right");
                EntityUtil.CheckArgumentNull(node, "node");
                EntityUtil.CheckArgumentNull(parent, "parent");

                m_left = left;
                m_right = right;
                m_joinExpression = node;
                m_parent = parent;

                Debug.Assert(DbExpressionKind.LeftOuterJoin == node.ExpressionKind || DbExpressionKind.InnerJoin == node.ExpressionKind, "(Update/JoinPropagagtor/JoinEvaluator) " +
                    "caller must ensure only left outer and inner joins are requested");
                // Retrieve propagation rules for the join type of the expression.
                if (DbExpressionKind.InnerJoin == m_joinExpression.ExpressionKind)
                {
                    m_insertRules = s_innerJoinInsertRules;
                    m_deleteRules = s_innerJoinDeleteRules;
                }
                else
                {
                    m_insertRules = s_leftOuterJoinInsertRules;
                    m_deleteRules = s_leftOuterJoinDeleteRules;
                }

                // Figure out key selectors involved in the equi-join (if it isn't an equi-join, we don't support it)
                JoinConditionVisitor.GetKeySelectors(node.JoinCondition, out m_leftKeySelectors, out m_rightKeySelectors);

                // Find the key selector expressions in the left and right placeholders
                m_leftPlaceholderKey = ExtractKey(m_left.Placeholder, m_leftKeySelectors, m_parent);
                m_rightPlaceholderKey = ExtractKey(m_right.Placeholder, m_rightKeySelectors, m_parent);
            }
        public override Expression Visit(DbJoinExpression expression)
        {
            if (expression.ExpressionKind == DbExpressionKind.FullOuterJoin)
            {
                throw new NotSupportedException("Full outer join is not yet supported");
            }

            Expression left = this.Visit(expression.Left.Expression);
            Expression right = this.Visit(expression.Right.Expression);

            Type leftType = TypeHelper.GetElementType(left.Type);
            Type rightType = TypeHelper.GetElementType(right.Type);

            ParameterExpression leftParam =
                Expression.Parameter(leftType, expression.Left.VariableName);

            ParameterExpression rightParam = 
                Expression.Parameter(rightType, expression.Right.VariableName);

            using (this.CreateVariable(leftParam, leftParam.Name))
            using (this.CreateVariable(rightParam, rightParam.Name))
            {
                LambdaExpression joinCondition =
                    Expression.Lambda(
                        this.Visit(expression.JoinCondition),
                        rightParam);

                // The Where expression represents the join condition
                // The NMemory query compiler will optimize this into a Join expression

                Expression innerExpression =
                    this.queryMethodExpressionBuilder.Where(right, joinCondition);
                
                if (expression.ExpressionKind == DbExpressionKind.LeftOuterJoin)
                {
                    innerExpression =
                        queryMethodExpressionBuilder.DefaultIfEmpty(innerExpression);
                }

                // Collection expression for the SelectMany
                LambdaExpression collectionSelector =
                    Expression.Lambda(
                        Expression.Convert(
                            innerExpression,
                            typeof(IEnumerable<>).MakeGenericType(rightType)),
                    leftParam);

                Expression result = this.CreateCrossJoin(
                    left,
                    collectionSelector,
                    leftParam.Name,
                    rightParam.Name);

                return result;
            }
        }
Example #3
0
 public override void Visit(DbJoinExpression expression)
 {
   if (expression == null) throw new ArgumentException("expression");
   VisitExpressionBindingPre(expression.Left);
   VisitExpressionBindingPre(expression.Right);
   VisitExpression(expression.JoinCondition);
   VisitExpressionBindingPost(expression.Left);
   VisitExpressionBindingPost(expression.Right);
 }
 public override SqlFragment Visit(DbJoinExpression expression)
 {
     return HandleJoinExpression(expression.Left, expression.Right, 
         expression.ExpressionKind, expression.JoinCondition);
 }
 public override void Visit(DbJoinExpression e)
 {
     VisitExprKind(e.ExpressionKind);
     _key.Append('(');
     VisitBinding(e.Left);
     VisitBinding(e.Right);
     _key.Append('(');
     e.JoinCondition.Accept(this);
     _key.Append("))");
 }
		public override void Visit(DbJoinExpression expression)
		{
			throw new NotSupportedException("Visit(\"JoinExpression\") is not supported.");
		}
        /// <summary>
        ///     Visitor pattern method for <see cref="DbJoinExpression" />.
        /// </summary>
        /// <param name="expression"> The DbJoinExpression that is being visited. </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="expression" />
        ///     is null
        /// </exception>
        public override void Visit(DbJoinExpression expression)
        {
            // #433613: PreSharp warning 56506: Parameter 'expression' to this public method must be validated: A null-dereference can occur here.
            Check.NotNull(expression, "expression");

            VisitExpressionBindingPre(expression.Left);
            VisitExpressionBindingPre(expression.Right);

            VisitExpression(expression.JoinCondition);

            VisitExpressionBindingPost(expression.Left);
            VisitExpressionBindingPost(expression.Right);
        }
 public override void Visit(DbJoinExpression expression)
 {
     Contract.Requires(expression != null);
 }
 /// <summary>
 ///     Visitor pattern method for DbJoinExpression.
 /// </summary>
 /// <param name="expression"> The DbJoinExpression that is being visited. </param>
 public abstract void Visit(DbJoinExpression expression);
 public override void Visit(DbJoinExpression e)
 {
     Begin(e);
     Dump(e.Left, "Left");
     Dump(e.Right, "Right");
     Dump(e.JoinCondition, "JoinCondition");
     End(e);
 }
 public override void Visit(DbJoinExpression expression) { }
 public override DbExpression Visit(DbJoinExpression expression)
 {
     System.Diagnostics.Debug.Print("Visit(DbJoinExpression): {0}", expression);
     return base.Visit(expression);
 }
        /// <summary>
        ///     Visitor pattern method for <see cref="DbJoinExpression" />.
        /// </summary>
        /// <param name="expression"> The DbJoinExpression that is being visited. </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="expression" />
        ///     is null
        /// </exception>
        public override void Visit(DbJoinExpression expression)
        {
            Check.NotNull(expression, "expression");

            VisitExpressionBindingPre(expression.Left);
            VisitExpressionBindingPre(expression.Right);

            VisitExpression(expression.JoinCondition);

            VisitExpressionBindingPost(expression.Left);
            VisitExpressionBindingPost(expression.Right);
        }
Example #14
0
        /// <summary>
        /// Implements the visitor pattern for <see cref="T:System.Data.Common.CommandTrees.DbJoinExpression"/>.
        /// </summary>
        /// <param name="expression">The <see cref="T:System.Data.Common.CommandTrees.DbJoinExpression"/> that is visited.</param>
        public override void Visit(DbJoinExpression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }

            expression.Left.Expression.Accept(this);
            expression.Right.Expression.Accept(this);
            expression.JoinCondition.Accept(this);
        }
        /// <summary>
        /// Visitor pattern method for <see cref="DbJoinExpression"/>.
        /// </summary>
        /// <param name="expression">The DbJoinExpression that is being visited.</param>
        /// <exception cref="ArgumentNullException"><paramref name="expression"/> is null</exception>
        public override void Visit(DbJoinExpression expression)
        {
            VisitExpressionBindingPre(expression.Left);
            VisitExpressionBindingPre(expression.Right);

            VisitExpression(expression.JoinCondition);

            VisitExpressionBindingPost(expression.Left);
            VisitExpressionBindingPost(expression.Right);
        }