Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / internal / materialization / coordinator.cs / 1305376 / coordinator.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //----------------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Globalization; using System.Data.Objects.Internal; namespace System.Data.Common.Internal.Materialization { ////// A coordinator is responsible for tracking state and processing result in a root or nested query /// result collection. The coordinator exists within a graph, and knows its Parent, (First)Child, /// and Next sibling. This allows the Shaper to use the coordinator as a simple state machine when /// consuming store reader results. /// internal abstract class Coordinator { #region state ////// The factory used to generate this coordinator instance. Contains delegates used /// by the Shaper during result enumeration. /// internal readonly CoordinatorFactory CoordinatorFactory; ////// Parent coordinator (the coordinator producing rows containing this collection). /// If this is the root, null. /// internal readonly Coordinator Parent; ////// First coordinator for nested results below this collection. When reading a new row /// for this coordinator, we walk down to the Child. /// /// NOTE:: this cannot be readonly because we can't know both the parent and the child /// at initialization time; we set the Child in the parent's constructor. /// public Coordinator Child { get { return _child; } protected set { _child = value; } } private Coordinator _child; ////// Next coordinator at this depth. Once we're done consuming results for this reader, /// we move on to this.Next. /// internal readonly Coordinator Next; ////// Indicates whether data has been read for the collection being aggregated or yielded /// by this coordinator. /// public bool IsEntered { get { return _isEntered; } protected set { _isEntered = value; } } private bool _isEntered; ////// Indicates whether this is the top level coordinator for a query. /// internal bool IsRoot { get { return null == Parent; } } #endregion #region constructor protected Coordinator(CoordinatorFactory coordinatorFactory, Coordinator parent, Coordinator next) { this.CoordinatorFactory = coordinatorFactory; this.Parent = parent; this.Next = next; } #endregion #region "public" surface area ////// Registers this hierarchy of coordinators in the given shaper. /// internal void Initialize(Shaper shaper) { ResetCollection(shaper); // Add this coordinator to the appropriate state slot in the // shaper so that it is available to materialization delegates. shaper.State[this.CoordinatorFactory.StateSlot] = this; if (null != this.Child) { this.Child.Initialize(shaper); } if (null != this.Next) { this.Next.Initialize(shaper); } } ////// Determines the maximum depth of this subtree. /// internal int MaxDistanceToLeaf() { int maxDistance = 0; Coordinator child = this.Child; while (null != child) { maxDistance = Math.Max(maxDistance, child.MaxDistanceToLeaf() + 1); child = child.Next; } return maxDistance; } ////// This method is called when the current collection is finished and it's time to move to the next collection. /// Recursively initializes children and siblings as well. /// internal abstract void ResetCollection(Shaper shaper); ////// Precondition: the current row has data for the coordinator. /// Side-effects: updates keys currently stored in state and updates IsEntered if a new value is encountered. /// Determines whether the row contains the next element in this collection. /// internal bool HasNextElement(Shaper shaper) { // check if this row contains a new element for this coordinator bool result = false; if (!this.IsEntered || !this.CoordinatorFactory.CheckKeys(shaper)) { // remember initial keys values this.CoordinatorFactory.SetKeys(shaper); this.IsEntered = true; result = true; } return result; } ////// Precondition: the current row has data and contains a new element for the coordinator. /// Reads the next element in this collection. /// internal abstract void ReadNextElement(Shaper shaper); #endregion } ////// Typed internal class Coordinator/// : Coordinator { #region state internal readonly CoordinatorFactory TypedCoordinatorFactory; /// /// Exposes the Current element that has been materialized (and is being populated) by this coordinator. /// internal T Current { get { return _current; } } private T _current; ////// For ObjectResult, aggregates all elements for in the nested collection handled by this coordinator. /// private ICollection_elements; /// /// For ObjectResult, aggregates all elements as wrapped entities for in the nested collection handled by this coordinator. /// private List_wrappedElements; /// /// Delegate called when the current nested collection has been consumed. This is necessary in Span /// scenarios where an EntityCollection RelatedEnd is populated only when all related entities have /// been materialized. This version of the close handler works with wrapped entities. /// private Action> _handleClose; /// /// For nested, object-layer coordinators we want to collect all the elements we find and handle them /// when the root coordinator advances. Otherwise we just want to return them as we find them. /// private readonly bool IsUsingElementCollection; #endregion #region constructors internal Coordinator(CoordinatorFactorycoordinator, Coordinator parent, Coordinator next) : base(coordinator, parent, next) { this.TypedCoordinatorFactory = coordinator; // generate all children Coordinator nextChild = null; foreach (var nestedCoordinator in coordinator.NestedCoordinators.Reverse()) { // last child processed is first child... this.Child = nestedCoordinator.CreateCoordinator(this, nextChild); nextChild = this.Child; } this.IsUsingElementCollection = (!this.IsRoot && typeof(T) != typeof(RecordState)); } #endregion #region "public" surface area internal override void ResetCollection(Shaper shaper) { // Check to see if anyone has registered for notification when the current coordinator // is reset. if (null != _handleClose) { _handleClose(shaper, _wrappedElements); _handleClose = null; } // Reset is entered for this collection. this.IsEntered = false; if (IsUsingElementCollection) { _elements = this.TypedCoordinatorFactory.InitializeCollection(shaper); _wrappedElements = new List (); } if (null != this.Child) { this.Child.ResetCollection(shaper); } if (null != this.Next) { this.Next.ResetCollection(shaper); } } internal override void ReadNextElement(Shaper shaper) { T element; IEntityWrapper wrappedElement = null; try { if (this.TypedCoordinatorFactory.WrappedElement == null) { element = this.TypedCoordinatorFactory.Element(shaper); } else { wrappedElement = this.TypedCoordinatorFactory.WrappedElement(shaper); // This cast may throw, in which case it will be immediately caught // and the error handling expression will be used to get the appropriate error message. element = (T)wrappedElement.Entity; } } catch (Exception e) { if (EntityUtil.IsCatchableExceptionType(e)) { // Some errors can occur while a close handler is registered. This clears // out the handler so that ElementWithErrorHandling will report the correct // error rather than asserting on the missing close handler. ResetCollection(shaper); // call a variation of the "Element" delegate with more detailed // error handling (to produce a better exception message) element = this.TypedCoordinatorFactory.ElementWithErrorHandling(shaper); } // rethrow throw; } if (IsUsingElementCollection) { _elements.Add(element); if (wrappedElement != null) { _wrappedElements.Add(wrappedElement); } } else { _current = element; } } /// /// Sets the delegate called when this collection is closed. This close handler works on /// a collection of wrapped entities, rather than on the raw entity objects. /// internal void RegisterCloseHandler(Action> closeHandler) { Debug.Assert(null == _handleClose, "more than one handler for a collection close 'event'"); _handleClose = closeHandler; } /// /// Called when we're disposing the enumerator; /// internal void SetCurrentToDefault() { _current = default(T); } #endregion #region runtime callable code // Code in this section is called from the delegates produced by the Translator. It may // not show up if you search using Find All References ////// Returns a handle to the element aggregator for this nested collection. /// private IEnumerableGetElements() { return _elements; } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //----------------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Globalization; using System.Data.Objects.Internal; namespace System.Data.Common.Internal.Materialization { ////// A coordinator is responsible for tracking state and processing result in a root or nested query /// result collection. The coordinator exists within a graph, and knows its Parent, (First)Child, /// and Next sibling. This allows the Shaper to use the coordinator as a simple state machine when /// consuming store reader results. /// internal abstract class Coordinator { #region state ////// The factory used to generate this coordinator instance. Contains delegates used /// by the Shaper during result enumeration. /// internal readonly CoordinatorFactory CoordinatorFactory; ////// Parent coordinator (the coordinator producing rows containing this collection). /// If this is the root, null. /// internal readonly Coordinator Parent; ////// First coordinator for nested results below this collection. When reading a new row /// for this coordinator, we walk down to the Child. /// /// NOTE:: this cannot be readonly because we can't know both the parent and the child /// at initialization time; we set the Child in the parent's constructor. /// public Coordinator Child { get { return _child; } protected set { _child = value; } } private Coordinator _child; ////// Next coordinator at this depth. Once we're done consuming results for this reader, /// we move on to this.Next. /// internal readonly Coordinator Next; ////// Indicates whether data has been read for the collection being aggregated or yielded /// by this coordinator. /// public bool IsEntered { get { return _isEntered; } protected set { _isEntered = value; } } private bool _isEntered; ////// Indicates whether this is the top level coordinator for a query. /// internal bool IsRoot { get { return null == Parent; } } #endregion #region constructor protected Coordinator(CoordinatorFactory coordinatorFactory, Coordinator parent, Coordinator next) { this.CoordinatorFactory = coordinatorFactory; this.Parent = parent; this.Next = next; } #endregion #region "public" surface area ////// Registers this hierarchy of coordinators in the given shaper. /// internal void Initialize(Shaper shaper) { ResetCollection(shaper); // Add this coordinator to the appropriate state slot in the // shaper so that it is available to materialization delegates. shaper.State[this.CoordinatorFactory.StateSlot] = this; if (null != this.Child) { this.Child.Initialize(shaper); } if (null != this.Next) { this.Next.Initialize(shaper); } } ////// Determines the maximum depth of this subtree. /// internal int MaxDistanceToLeaf() { int maxDistance = 0; Coordinator child = this.Child; while (null != child) { maxDistance = Math.Max(maxDistance, child.MaxDistanceToLeaf() + 1); child = child.Next; } return maxDistance; } ////// This method is called when the current collection is finished and it's time to move to the next collection. /// Recursively initializes children and siblings as well. /// internal abstract void ResetCollection(Shaper shaper); ////// Precondition: the current row has data for the coordinator. /// Side-effects: updates keys currently stored in state and updates IsEntered if a new value is encountered. /// Determines whether the row contains the next element in this collection. /// internal bool HasNextElement(Shaper shaper) { // check if this row contains a new element for this coordinator bool result = false; if (!this.IsEntered || !this.CoordinatorFactory.CheckKeys(shaper)) { // remember initial keys values this.CoordinatorFactory.SetKeys(shaper); this.IsEntered = true; result = true; } return result; } ////// Precondition: the current row has data and contains a new element for the coordinator. /// Reads the next element in this collection. /// internal abstract void ReadNextElement(Shaper shaper); #endregion } ////// Typed internal class Coordinator/// : Coordinator { #region state internal readonly CoordinatorFactory TypedCoordinatorFactory; /// /// Exposes the Current element that has been materialized (and is being populated) by this coordinator. /// internal T Current { get { return _current; } } private T _current; ////// For ObjectResult, aggregates all elements for in the nested collection handled by this coordinator. /// private ICollection_elements; /// /// For ObjectResult, aggregates all elements as wrapped entities for in the nested collection handled by this coordinator. /// private List_wrappedElements; /// /// Delegate called when the current nested collection has been consumed. This is necessary in Span /// scenarios where an EntityCollection RelatedEnd is populated only when all related entities have /// been materialized. This version of the close handler works with wrapped entities. /// private Action> _handleClose; /// /// For nested, object-layer coordinators we want to collect all the elements we find and handle them /// when the root coordinator advances. Otherwise we just want to return them as we find them. /// private readonly bool IsUsingElementCollection; #endregion #region constructors internal Coordinator(CoordinatorFactorycoordinator, Coordinator parent, Coordinator next) : base(coordinator, parent, next) { this.TypedCoordinatorFactory = coordinator; // generate all children Coordinator nextChild = null; foreach (var nestedCoordinator in coordinator.NestedCoordinators.Reverse()) { // last child processed is first child... this.Child = nestedCoordinator.CreateCoordinator(this, nextChild); nextChild = this.Child; } this.IsUsingElementCollection = (!this.IsRoot && typeof(T) != typeof(RecordState)); } #endregion #region "public" surface area internal override void ResetCollection(Shaper shaper) { // Check to see if anyone has registered for notification when the current coordinator // is reset. if (null != _handleClose) { _handleClose(shaper, _wrappedElements); _handleClose = null; } // Reset is entered for this collection. this.IsEntered = false; if (IsUsingElementCollection) { _elements = this.TypedCoordinatorFactory.InitializeCollection(shaper); _wrappedElements = new List (); } if (null != this.Child) { this.Child.ResetCollection(shaper); } if (null != this.Next) { this.Next.ResetCollection(shaper); } } internal override void ReadNextElement(Shaper shaper) { T element; IEntityWrapper wrappedElement = null; try { if (this.TypedCoordinatorFactory.WrappedElement == null) { element = this.TypedCoordinatorFactory.Element(shaper); } else { wrappedElement = this.TypedCoordinatorFactory.WrappedElement(shaper); // This cast may throw, in which case it will be immediately caught // and the error handling expression will be used to get the appropriate error message. element = (T)wrappedElement.Entity; } } catch (Exception e) { if (EntityUtil.IsCatchableExceptionType(e)) { // Some errors can occur while a close handler is registered. This clears // out the handler so that ElementWithErrorHandling will report the correct // error rather than asserting on the missing close handler. ResetCollection(shaper); // call a variation of the "Element" delegate with more detailed // error handling (to produce a better exception message) element = this.TypedCoordinatorFactory.ElementWithErrorHandling(shaper); } // rethrow throw; } if (IsUsingElementCollection) { _elements.Add(element); if (wrappedElement != null) { _wrappedElements.Add(wrappedElement); } } else { _current = element; } } /// /// Sets the delegate called when this collection is closed. This close handler works on /// a collection of wrapped entities, rather than on the raw entity objects. /// internal void RegisterCloseHandler(Action> closeHandler) { Debug.Assert(null == _handleClose, "more than one handler for a collection close 'event'"); _handleClose = closeHandler; } /// /// Called when we're disposing the enumerator; /// internal void SetCurrentToDefault() { _current = default(T); } #endregion #region runtime callable code // Code in this section is called from the delegates produced by the Translator. It may // not show up if you search using Find All References ////// Returns a handle to the element aggregator for this nested collection. /// private IEnumerableGetElements() { return _elements; } #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
- ProcessRequestArgs.cs
- MoveSizeWinEventHandler.cs
- Cursor.cs
- DataGridViewButtonColumn.cs
- DateTimeSerializationSection.cs
- SpellCheck.cs
- XmlTextReaderImplHelpers.cs
- JsonSerializer.cs
- ToolStripRenderer.cs
- ScaleTransform3D.cs
- NonSerializedAttribute.cs
- ListControlConvertEventArgs.cs
- TextBoxDesigner.cs
- StorageConditionPropertyMapping.cs
- PolyQuadraticBezierSegment.cs
- XamlSerializerUtil.cs
- DataGridViewColumnStateChangedEventArgs.cs
- AssemblyBuilder.cs
- DataStreams.cs
- ZipFileInfo.cs
- New.cs
- DoubleStorage.cs
- dataobject.cs
- ScriptBehaviorDescriptor.cs
- WebScriptMetadataMessageEncoderFactory.cs
- WhileDesigner.cs
- __FastResourceComparer.cs
- ExternalFile.cs
- ObjectDisposedException.cs
- PackageRelationship.cs
- DataGridViewRowCollection.cs
- PerformanceCounterNameAttribute.cs
- CompiledRegexRunnerFactory.cs
- SslStream.cs
- XPathNavigatorReader.cs
- CanonicalFontFamilyReference.cs
- XmlSchemaIdentityConstraint.cs
- FloaterParaClient.cs
- RuntimeResourceSet.cs
- XmlAttributeHolder.cs
- X509IssuerSerialKeyIdentifierClause.cs
- TransactionsSectionGroup.cs
- NativeActivityTransactionContext.cs
- XmlSerializerVersionAttribute.cs
- ToolboxDataAttribute.cs
- RemoteWebConfigurationHostStream.cs
- securestring.cs
- MemberCollection.cs
- SByteStorage.cs
- Barrier.cs
- StateMachineWorkflow.cs
- TableLayoutColumnStyleCollection.cs
- LinqDataSourceDisposeEventArgs.cs
- StringExpressionSet.cs
- StylusPlugInCollection.cs
- EntityCollection.cs
- ProxyFragment.cs
- TypeDescriptionProvider.cs
- ContextMenuStrip.cs
- EmptyQuery.cs
- PreviewKeyDownEventArgs.cs
- ChildrenQuery.cs
- WarningException.cs
- StructuredProperty.cs
- SortQuery.cs
- NetTcpBindingElement.cs
- ToolStripPanelRow.cs
- ValidateNames.cs
- SqlCachedBuffer.cs
- ValidatorUtils.cs
- TraceEventCache.cs
- BasicExpandProvider.cs
- ValidateNames.cs
- VisualBrush.cs
- ValidatingPropertiesEventArgs.cs
- OleDbSchemaGuid.cs
- ACL.cs
- ToolStripContainer.cs
- AppSettingsSection.cs
- ColorKeyFrameCollection.cs
- SqlExpander.cs
- TextHidden.cs
- EncryptedPackageFilter.cs
- BackStopAuthenticationModule.cs
- RegexMatchCollection.cs
- LineSegment.cs
- ConfigurationStrings.cs
- FontCollection.cs
- followingquery.cs
- SeekableReadStream.cs
- OperationAbortedException.cs
- EncryptedKey.cs
- SqlBooleanizer.cs
- DataGridViewCellCancelEventArgs.cs
- Thread.cs
- DynamicResourceExtensionConverter.cs
- SqlDataSourceCommandParser.cs
- DesignerAttribute.cs
- ImageIndexConverter.cs
- ScrollableControl.cs