Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / Update / Internal / Propagator.cs / 1305376 / Propagator.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Metadata.Edm; using System.Data.Common.CommandTrees; using System.Collections.Generic; using System.Diagnostics; using System.Data.Common.Utils; namespace System.Data.Mapping.Update.Internal { ////// ////// Comments assume there is a map between the CDM and store. Other maps are possible, but /// for simplicity, we discuss the 'from' portion of the map as the C-Space and the 'to' portion /// of the map as the S-Space. /// ////// This class translates C-Space change requests into S-Space change requests given a C-Space change /// request, an update view loader, and a target table. It has precisely one entry /// point, the static ///method. It performs the translation by evaluating an update /// mapping view w.r.t. change requests (propagating a change request through the view). /// /// internal partial class Propagator : UpdateExpressionVisitor/// This class implements propagation rules for the following relational operators in the update mapping /// view: /// //////
///- Projection
///- Selection (filter)
///- Union all
///- Inner equijoin
///- Left outer equijoin
///{ #region Constructors /// /// Construct a new propagator. /// /// UpdateTranslator supporting retrieval of changes for C-Space /// extents referenced in the update mapping view. /// Table for which updates are being produced. private Propagator(UpdateTranslator parent, EntitySet table) { // Initialize propagator state. EntityUtil.CheckArgumentNull(parent, "parent"); EntityUtil.CheckArgumentNull(table, "table"); m_updateTranslator = parent; m_table = table; } #endregion #region Fields private readonly UpdateTranslator m_updateTranslator; private readonly EntitySet m_table; private static readonly string s_visitorName = typeof(Propagator).FullName; #endregion #region Properties ////// Gets context for updates performed by this propagator. /// internal UpdateTranslator UpdateTranslator { get { return m_updateTranslator; } } override protected string VisitorName { get { return s_visitorName; } } #endregion #region Methods ////// Propagate changes from C-Space (contained in ///to the S-Space. /// /// See Walker class for an explanation of this coding pattern. /// /// Grouper supporting retrieval of changes for C-Space /// extents referenced in the update mapping view. /// Table for which updates are being produced. /// Update mapping view to propagate. ///Changes in S-Space. static internal 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). DbExpressionVisitorpropagator = 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); } /// /// Utility method constructs a new empty change node. /// /// Update mapping view node associated with the change. ///Empty change node with the appropriate type for the view node. private static ChangeNode BuildChangeNode(DbExpression node) { TypeUsage nodeType = node.ResultType; TypeUsage elementType = MetadataHelper.GetElementType(nodeType); return new ChangeNode(elementType); } #region Visitor implementation public override ChangeNode Visit(DbCrossJoinExpression node) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Update_UnsupportedJoinType(node.ExpressionKind)); } ////// Propagates changes across a join expression node by implementing progation rules w.r.t. inputs /// from the left- and right- hand sides of the join. The work is actually performed /// by the /// A join expression node. ///. /// Results propagated to the given join expression node. public override ChangeNode Visit(DbJoinExpression node) { EntityUtil.CheckArgumentNull(node, "node"); if (DbExpressionKind.InnerJoin != node.ExpressionKind && DbExpressionKind.LeftOuterJoin != node.ExpressionKind) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Update_UnsupportedJoinType(node.ExpressionKind)); } // There are precisely two inputs to the join which we treat as the left and right children. DbExpression leftExpr = node.Left.Expression; DbExpression rightExpr = node.Right.Expression; // Get the results of propagating changes to the left and right inputs to the join. ChangeNode left = Visit(leftExpr); ChangeNode right = Visit(rightExpr); // Construct a new join propagator, passing in the left and right results, the actual // join expression, and this parent propagator. JoinPropagator evaluator = new JoinPropagator(left, right, node, this); // Execute propagation. ChangeNode result = evaluator.Propagate(); return result; } ////// Given the results returned for the left and right inputs to a union, propagates changes /// through the union. /// /// Propagation rule (U = union node, L = left input, R = right input, D(x) = deleted rows /// in x, I(x) = inserted rows in x) /// /// U = L union R /// D(U) = D(L) union D(R) /// I(U) = I(L) union I(R) /// /// Union expression node in the update mapping view. ///Result of propagating changes to this union all node. public override ChangeNode Visit(DbUnionAllExpression node) { EntityUtil.CheckArgumentNull(node, "node"); // Initialize an empty change node result for the union all node ChangeNode result = BuildChangeNode(node); // Retrieve result of propagating changes to the left and right children. ChangeNode left = Visit(node.Left); ChangeNode right = Visit(node.Right); // Implement insertion propagation rule I(U) = I(L) union I(R) result.Inserted.AddRange(left.Inserted); result.Inserted.AddRange(right.Inserted); // Implement deletion progation rule D(U) = D(L) union D(R) result.Deleted.AddRange(left.Deleted); result.Deleted.AddRange(right.Deleted); // The choice of side for the placeholder is arbitrary, since CQTs enforce type compatibility // for the left and right hand sides of the union. result.Placeholder = left.Placeholder; return result; } ////// Propagate projection. /// /// Propagation rule (P = projection node, S = projection input, D(x) = deleted rows in x, /// I(x) = inserted rows in x) /// /// P = Proj_f S /// D(P) = Proj_f D(S) /// I(P) = Proj_f I(S) /// /// Projection expression node. ///Result of propagating changes to the projection expression node. public override ChangeNode Visit(DbProjectExpression node) { EntityUtil.CheckArgumentNull(node, "node"); // Initialize an empty change node result for the projection node. ChangeNode result = BuildChangeNode(node); // Retrieve result of propagating changes to the input of the projection. ChangeNode input = Visit(node.Input.Expression); // Implement propagation rule for insert I(P) = Proj_f I(S) foreach(PropagatorResult row in input.Inserted) { result.Inserted.Add(Project(node, row, result.ElementType)); } // Implement propagation rule for delete D(P) = Proj_f D(S) foreach(PropagatorResult row in input.Deleted) { result.Deleted.Add(Project(node, row, result.ElementType)); } // Generate a placeholder for the projection node by projecting values in the // placeholder for the input node. result.Placeholder = Project(node, input.Placeholder, result.ElementType); return result; } ////// Performs projection for a single row. Evaluates each projection argument against the specified /// row, returning a result with the specified type. /// /// Projection expression. /// Row to project. /// Type of the projected row. ///Projected row. private PropagatorResult Project(DbProjectExpression node, PropagatorResult row, TypeUsage resultType) { EntityUtil.CheckArgumentNull(node, "node"); Debug.Assert(null != node.Projection, "CQT validates DbProjectExpression.Projection property"); DbNewInstanceExpression projection = node.Projection as DbNewInstanceExpression; if (null == projection) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Update_UnsupportedProjection(node.Projection.ExpressionKind)); } // Initialize empty structure containing space for every element of the projection. PropagatorResult[] projectedValues = new PropagatorResult[projection.Arguments.Count]; // Extract value from the input row for every projection argument requested. for (int ordinal = 0; ordinal < projectedValues.Length; ordinal++) { projectedValues[ordinal] = Evaluator.Evaluate(projection.Arguments[ordinal], row, this); } // Return a new row containing projected values. PropagatorResult projectedRow = PropagatorResult.CreateStructuralValue(projectedValues, (StructuralType)resultType.EdmType, false); return projectedRow; } ////// Propagation rule (F = filter node, S = input to filter, I(x) = rows inserted /// into x, D(x) = rows deleted from x, Sigma_p = filter predicate) /// /// F = Sigma_p S /// D(F) = Sigma_p D(S) /// I(F) = Sigma_p I(S) /// /// ///public override ChangeNode Visit(DbFilterExpression node) { EntityUtil.CheckArgumentNull(node, "node"); // Initialize an empty change node for this filter node. ChangeNode result = BuildChangeNode(node); // Retrieve result of propagating changes to the input of the filter. ChangeNode input = Visit(node.Input.Expression); // Implement insert propagation rule I(F) = Sigma_p I(S) result.Inserted.AddRange(Evaluator.Filter(node.Predicate, input.Inserted, this)); // Implement delete propagation rule D(F) = Sigma_p D(S result.Deleted.AddRange(Evaluator.Filter(node.Predicate, input.Deleted, this)); // The placeholder for a filter node is identical to that of the input, which has an // identical shape (type). result.Placeholder = input.Placeholder; return result; } /// /// Handles extent expressions (these are the terminal nodes in update mapping views). This handler /// retrieves the changes from the grouper. /// /// Extent expression node ///public override ChangeNode Visit(DbScanExpression node) { EntityUtil.CheckArgumentNull(node, "node"); // Gets modifications requested for this extent from the grouper. EntitySetBase extent = node.Target; ChangeNode extentModifications = UpdateTranslator.GetExtentModifications(extent); if (null == extentModifications.Placeholder) { // Bootstrap placeholder (essentially a record for the extent populated with default values). extentModifications.Placeholder = ExtentPlaceholderCreator.CreatePlaceholder(extent, UpdateTranslator); } return extentModifications; } #endregion #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Metadata.Edm; using System.Data.Common.CommandTrees; using System.Collections.Generic; using System.Diagnostics; using System.Data.Common.Utils; namespace System.Data.Mapping.Update.Internal { ////// ////// Comments assume there is a map between the CDM and store. Other maps are possible, but /// for simplicity, we discuss the 'from' portion of the map as the C-Space and the 'to' portion /// of the map as the S-Space. /// ////// This class translates C-Space change requests into S-Space change requests given a C-Space change /// request, an update view loader, and a target table. It has precisely one entry /// point, the static ///method. It performs the translation by evaluating an update /// mapping view w.r.t. change requests (propagating a change request through the view). /// /// internal partial class Propagator : UpdateExpressionVisitor/// This class implements propagation rules for the following relational operators in the update mapping /// view: /// //////
///- Projection
///- Selection (filter)
///- Union all
///- Inner equijoin
///- Left outer equijoin
///{ #region Constructors /// /// Construct a new propagator. /// /// UpdateTranslator supporting retrieval of changes for C-Space /// extents referenced in the update mapping view. /// Table for which updates are being produced. private Propagator(UpdateTranslator parent, EntitySet table) { // Initialize propagator state. EntityUtil.CheckArgumentNull(parent, "parent"); EntityUtil.CheckArgumentNull(table, "table"); m_updateTranslator = parent; m_table = table; } #endregion #region Fields private readonly UpdateTranslator m_updateTranslator; private readonly EntitySet m_table; private static readonly string s_visitorName = typeof(Propagator).FullName; #endregion #region Properties ////// Gets context for updates performed by this propagator. /// internal UpdateTranslator UpdateTranslator { get { return m_updateTranslator; } } override protected string VisitorName { get { return s_visitorName; } } #endregion #region Methods ////// Propagate changes from C-Space (contained in ///to the S-Space. /// /// See Walker class for an explanation of this coding pattern. /// /// Grouper supporting retrieval of changes for C-Space /// extents referenced in the update mapping view. /// Table for which updates are being produced. /// Update mapping view to propagate. ///Changes in S-Space. static internal 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). DbExpressionVisitorpropagator = 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); } /// /// Utility method constructs a new empty change node. /// /// Update mapping view node associated with the change. ///Empty change node with the appropriate type for the view node. private static ChangeNode BuildChangeNode(DbExpression node) { TypeUsage nodeType = node.ResultType; TypeUsage elementType = MetadataHelper.GetElementType(nodeType); return new ChangeNode(elementType); } #region Visitor implementation public override ChangeNode Visit(DbCrossJoinExpression node) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Update_UnsupportedJoinType(node.ExpressionKind)); } ////// Propagates changes across a join expression node by implementing progation rules w.r.t. inputs /// from the left- and right- hand sides of the join. The work is actually performed /// by the /// A join expression node. ///. /// Results propagated to the given join expression node. public override ChangeNode Visit(DbJoinExpression node) { EntityUtil.CheckArgumentNull(node, "node"); if (DbExpressionKind.InnerJoin != node.ExpressionKind && DbExpressionKind.LeftOuterJoin != node.ExpressionKind) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Update_UnsupportedJoinType(node.ExpressionKind)); } // There are precisely two inputs to the join which we treat as the left and right children. DbExpression leftExpr = node.Left.Expression; DbExpression rightExpr = node.Right.Expression; // Get the results of propagating changes to the left and right inputs to the join. ChangeNode left = Visit(leftExpr); ChangeNode right = Visit(rightExpr); // Construct a new join propagator, passing in the left and right results, the actual // join expression, and this parent propagator. JoinPropagator evaluator = new JoinPropagator(left, right, node, this); // Execute propagation. ChangeNode result = evaluator.Propagate(); return result; } ////// Given the results returned for the left and right inputs to a union, propagates changes /// through the union. /// /// Propagation rule (U = union node, L = left input, R = right input, D(x) = deleted rows /// in x, I(x) = inserted rows in x) /// /// U = L union R /// D(U) = D(L) union D(R) /// I(U) = I(L) union I(R) /// /// Union expression node in the update mapping view. ///Result of propagating changes to this union all node. public override ChangeNode Visit(DbUnionAllExpression node) { EntityUtil.CheckArgumentNull(node, "node"); // Initialize an empty change node result for the union all node ChangeNode result = BuildChangeNode(node); // Retrieve result of propagating changes to the left and right children. ChangeNode left = Visit(node.Left); ChangeNode right = Visit(node.Right); // Implement insertion propagation rule I(U) = I(L) union I(R) result.Inserted.AddRange(left.Inserted); result.Inserted.AddRange(right.Inserted); // Implement deletion progation rule D(U) = D(L) union D(R) result.Deleted.AddRange(left.Deleted); result.Deleted.AddRange(right.Deleted); // The choice of side for the placeholder is arbitrary, since CQTs enforce type compatibility // for the left and right hand sides of the union. result.Placeholder = left.Placeholder; return result; } ////// Propagate projection. /// /// Propagation rule (P = projection node, S = projection input, D(x) = deleted rows in x, /// I(x) = inserted rows in x) /// /// P = Proj_f S /// D(P) = Proj_f D(S) /// I(P) = Proj_f I(S) /// /// Projection expression node. ///Result of propagating changes to the projection expression node. public override ChangeNode Visit(DbProjectExpression node) { EntityUtil.CheckArgumentNull(node, "node"); // Initialize an empty change node result for the projection node. ChangeNode result = BuildChangeNode(node); // Retrieve result of propagating changes to the input of the projection. ChangeNode input = Visit(node.Input.Expression); // Implement propagation rule for insert I(P) = Proj_f I(S) foreach(PropagatorResult row in input.Inserted) { result.Inserted.Add(Project(node, row, result.ElementType)); } // Implement propagation rule for delete D(P) = Proj_f D(S) foreach(PropagatorResult row in input.Deleted) { result.Deleted.Add(Project(node, row, result.ElementType)); } // Generate a placeholder for the projection node by projecting values in the // placeholder for the input node. result.Placeholder = Project(node, input.Placeholder, result.ElementType); return result; } ////// Performs projection for a single row. Evaluates each projection argument against the specified /// row, returning a result with the specified type. /// /// Projection expression. /// Row to project. /// Type of the projected row. ///Projected row. private PropagatorResult Project(DbProjectExpression node, PropagatorResult row, TypeUsage resultType) { EntityUtil.CheckArgumentNull(node, "node"); Debug.Assert(null != node.Projection, "CQT validates DbProjectExpression.Projection property"); DbNewInstanceExpression projection = node.Projection as DbNewInstanceExpression; if (null == projection) { throw EntityUtil.NotSupported(System.Data.Entity.Strings.Update_UnsupportedProjection(node.Projection.ExpressionKind)); } // Initialize empty structure containing space for every element of the projection. PropagatorResult[] projectedValues = new PropagatorResult[projection.Arguments.Count]; // Extract value from the input row for every projection argument requested. for (int ordinal = 0; ordinal < projectedValues.Length; ordinal++) { projectedValues[ordinal] = Evaluator.Evaluate(projection.Arguments[ordinal], row, this); } // Return a new row containing projected values. PropagatorResult projectedRow = PropagatorResult.CreateStructuralValue(projectedValues, (StructuralType)resultType.EdmType, false); return projectedRow; } ////// Propagation rule (F = filter node, S = input to filter, I(x) = rows inserted /// into x, D(x) = rows deleted from x, Sigma_p = filter predicate) /// /// F = Sigma_p S /// D(F) = Sigma_p D(S) /// I(F) = Sigma_p I(S) /// /// ///public override ChangeNode Visit(DbFilterExpression node) { EntityUtil.CheckArgumentNull(node, "node"); // Initialize an empty change node for this filter node. ChangeNode result = BuildChangeNode(node); // Retrieve result of propagating changes to the input of the filter. ChangeNode input = Visit(node.Input.Expression); // Implement insert propagation rule I(F) = Sigma_p I(S) result.Inserted.AddRange(Evaluator.Filter(node.Predicate, input.Inserted, this)); // Implement delete propagation rule D(F) = Sigma_p D(S result.Deleted.AddRange(Evaluator.Filter(node.Predicate, input.Deleted, this)); // The placeholder for a filter node is identical to that of the input, which has an // identical shape (type). result.Placeholder = input.Placeholder; return result; } /// /// Handles extent expressions (these are the terminal nodes in update mapping views). This handler /// retrieves the changes from the grouper. /// /// Extent expression node ///public override ChangeNode Visit(DbScanExpression node) { EntityUtil.CheckArgumentNull(node, "node"); // Gets modifications requested for this extent from the grouper. EntitySetBase extent = node.Target; ChangeNode extentModifications = UpdateTranslator.GetExtentModifications(extent); if (null == extentModifications.Placeholder) { // Bootstrap placeholder (essentially a record for the extent populated with default values). extentModifications.Placeholder = ExtentPlaceholderCreator.CreatePlaceholder(extent, UpdateTranslator); } return extentModifications; } #endregion #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Comparer.cs
- SrgsOneOf.cs
- ICspAsymmetricAlgorithm.cs
- RequestSecurityTokenResponseCollection.cs
- SudsWriter.cs
- HttpProcessUtility.cs
- OdbcCommand.cs
- StatusBarItem.cs
- PeerTransportSecurityElement.cs
- InvalidateEvent.cs
- SymbolMethod.cs
- MarshalByValueComponent.cs
- MemoryFailPoint.cs
- CalendarTable.cs
- StandardToolWindows.cs
- SelectionList.cs
- WebResourceUtil.cs
- CacheOutputQuery.cs
- RenderCapability.cs
- MergeLocalizationDirectives.cs
- WaveHeader.cs
- AndCondition.cs
- ZoneMembershipCondition.cs
- TableDetailsCollection.cs
- SymbolUsageManager.cs
- CopyCodeAction.cs
- RegexGroupCollection.cs
- OdbcPermission.cs
- GeometryCombineModeValidation.cs
- UpdateCommand.cs
- FontUnit.cs
- ValidatorCollection.cs
- ApplyImportsAction.cs
- TextSimpleMarkerProperties.cs
- CodeCastExpression.cs
- ConfigurationSection.cs
- WebPartConnectionsConfigureVerb.cs
- CryptoApi.cs
- RemoteWebConfigurationHost.cs
- SecondaryViewProvider.cs
- XmlSerializerObjectSerializer.cs
- OperationCanceledException.cs
- BmpBitmapEncoder.cs
- FlowDocumentReaderAutomationPeer.cs
- URLIdentityPermission.cs
- NativeMethods.cs
- PageRequestManager.cs
- SystemResources.cs
- RelationshipManager.cs
- IDQuery.cs
- UriExt.cs
- ManipulationCompletedEventArgs.cs
- PermissionToken.cs
- EncodingTable.cs
- SqlDataSourceQuery.cs
- TextTreeTextBlock.cs
- Roles.cs
- ObjectSet.cs
- XmlHelper.cs
- SmiXetterAccessMap.cs
- MenuCommand.cs
- SimpleBitVector32.cs
- HtmlTextArea.cs
- MenuAdapter.cs
- ConstructorNeedsTagAttribute.cs
- CryptoConfig.cs
- RegexFCD.cs
- DiscoveryClient.cs
- ISFTagAndGuidCache.cs
- PersonalizableAttribute.cs
- AdvancedBindingEditor.cs
- WaitHandle.cs
- sqlmetadatafactory.cs
- CodeDirectoryCompiler.cs
- LayoutEditorPart.cs
- BindingExpressionUncommonField.cs
- WorkflowServiceAttributes.cs
- StringFreezingAttribute.cs
- EncryptedKey.cs
- CheckBoxDesigner.cs
- RewritingPass.cs
- HotCommands.cs
- RunWorkerCompletedEventArgs.cs
- Stack.cs
- CrossAppDomainChannel.cs
- ToolStripStatusLabel.cs
- DateTimeFormatInfoScanner.cs
- UnicodeEncoding.cs
- Attributes.cs
- CollectionChange.cs
- HttpListenerContext.cs
- ComplusTypeValidator.cs
- ServicePointManagerElement.cs
- String.cs
- Predicate.cs
- FaultContractAttribute.cs
- MergeLocalizationDirectives.cs
- DataGridViewTopLeftHeaderCell.cs
- TextEditorCopyPaste.cs
- GeneralTransform2DTo3D.cs