// <summary> // Propagate changes from C-Space (contained in <paramref name="parent" /> to the S-Space. // </summary> // <remarks> // See Walker class for an explanation of this coding pattern. // </remarks> // <param name="parent"> Grouper supporting retrieval of changes for C-Space extents referenced in the update mapping view. </param> // <param name="table"> Table for which updates are being produced. </param> // <param name="umView"> Update mapping view to propagate. </param> // <returns> Changes in S-Space. </returns> internal static ChangeNode Propagate(UpdateTranslator parent, EntitySet table, DbQueryCommandTree umView) { // Construct a new instance of a propagator, which implements a visitor interface // for expression nodes (nodes in the update mapping view) and returns changes nodes // (seeded by C-Space extent changes returned by the grouper). DbExpressionVisitor <ChangeNode> propagator = new Propagator(parent, table); // Walk the update mapping view using the visitor pattern implemented in this class. // The update mapping view describes the S-Space table we're targeting, so the result // returned for the root of view corresponds to changes propagated to the S-Space. return(umView.Query.Accept(propagator)); }
// <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) { DebugCheck.NotNull(left); DebugCheck.NotNull(right); DebugCheck.NotNull(node); DebugCheck.NotNull(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 = _innerJoinInsertRules; m_deleteRules = _innerJoinDeleteRules; } else { m_insertRules = _leftOuterJoinInsertRules; m_deleteRules = _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_rightPlaceholderKey = ExtractKey(m_right.Placeholder, m_rightKeySelectors); }