Example #1
0
            /// <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);
            }
Example #2
0
                /// <summary>
                /// Determine properties from the left and right inputs to an equi-join participating
                /// in predicate.
                /// </summary>
                /// <remarks>
                /// The property definitions returned are 'aligned'. If the join predicate reads:
                /// <code>
                /// a = b AND c = d AND e = f
                /// </code>
                /// then the output is as follows:
                /// <code>
                /// leftProperties = {a, c, e}
                /// rightProperties = {b, d, f}
                /// </code>
                /// See Walker class for an explanation of this coding pattern.
                /// </remarks>
                static internal void GetKeySelectors(DbExpression joinCondition, out ReadOnlyCollection <DbExpression> leftKeySelectors, out ReadOnlyCollection <DbExpression> rightKeySelectors)
                {
                    EntityUtil.CheckArgumentNull(joinCondition, "joinCondition");

                    // Constructs a new predicate visitor, which implements a visitor for expression nodes
                    // and returns no values. This visitor instead builds up a list of properties as leaves
                    // of the join predicate are visited.
                    JoinConditionVisitor visitor = new JoinConditionVisitor();

                    // Walk the predicate using the predicate visitor.
                    joinCondition.Accept(visitor);

                    // Retrieve properties discovered visiting predicate leaf nodes.
                    leftKeySelectors  = visitor.m_leftKeySelectors.AsReadOnly();
                    rightKeySelectors = visitor.m_rightKeySelectors.AsReadOnly();

                    Debug.Assert(leftKeySelectors.Count == rightKeySelectors.Count,
                                 "(Update/JoinPropagator) The equi-join must have an equal number of left and right properties");
                }