Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / System / data / design / TableAdapterManagerHelper.cs / 3 / TableAdapterManagerHelper.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // //----------------------------------------------------------------------------- namespace System.Data.Design { using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Diagnostics; using System.ComponentModel; internal class TableAdapterManagerHelper { ////// Find out the self referenced relation /// Rule: if there is multiple self-ref relations, /// and if there is relations with FK, they and only they will be returned /// otherewise, return all self-ref relations /// /// Example: table has RELFK1,RELFK2,REL3 --> return RELFK1,RELFK2 /// Example: table has REL3, REL4 --> return REL3, REL4 /// Example: table has FK1,FK2 --> return null /// /// the dataTable ///the selfRef relations for this table. internal static DataRelation[] GetSelfRefRelations(DataTable dataTable) { Debug.Assert(dataTable != null); ListselfRefs = new List (); List selfRefWithFKs = new List (); foreach (DataRelation relation in dataTable.ParentRelations) { if (relation.ChildTable == relation.ParentTable){ selfRefs.Add(relation); if (relation.ChildKeyConstraint != null) { selfRefWithFKs.Add(relation); } } } if (selfRefWithFKs.Count > 0) { return selfRefWithFKs.ToArray(); } return selfRefs.ToArray(); } /// /// Find out the hierarchical update order based on the first FKs then the relations. /// Example, customer(parent of order), order(parent of orderdetail), orderdetail /// --> out put will be Customer, Order, OrderDetail /// Self-referece is not considered in the order /// Circle referece will stop the searching once detected /// /// the dataset ///DataTable array with parents first internal static DataTable[] GetUpdateOrder(DataSet ds) { // Find out the tables that get involved, then build a tree HierarchicalObject[] orders = new HierarchicalObject[ds.Tables.Count]; for (int i = 0; i < ds.Tables.Count; i++) { DataTable t = ds.Tables[i]; HierarchicalObject ho = new HierarchicalObject(t); orders[i] = ho; } // First, build up the parent tree for (int i = 0; i < orders.Length; i++) { DataTable t = orders[i].TheObject as DataTable; // build HU parent relation tree based on FK foreach (Constraint c in t.Constraints) { ForeignKeyConstraint fc = c as ForeignKeyConstraint; // We do not care if the rule is turned on or not // We do not consider self referenced FK if (fc != null && !Object.ReferenceEquals(fc.RelatedTable, t)) { int index = ds.Tables.IndexOf(fc.RelatedTable); Debug.Assert(index >= 0); orders[i].AddUniqueParent(orders[index]); } } // build HU parent relation tree based on relation foreach (DataRelation relation in t.ParentRelations) { if (!object.ReferenceEquals(relation.ParentTable, t)) { int index = ds.Tables.IndexOf(relation.ParentTable); Debug.Assert(index >= 0); orders[i].AddUniqueParent(orders[index]); } } } // Work out the priorities for (int i = 0; i < orders.Length; i++) { HierarchicalObject ho = orders[i]; if (ho.HasParent) { ho.CheckParents(); } } // Get the result with sorted order DataTable[] dataTables = new DataTable[orders.Length]; System.Array.Sort(orders); for (int i = 0; i < orders.Length; i++) { HierarchicalObject ho = orders[i]; dataTables[i] = (DataTable)ho.TheObject; } return dataTables; } /// /// The object with a list of parents /// internal class HierarchicalObject : IComparable{ internal int Height = 0; // the hierarchical priority internal Object TheObject; private List parents; internal List Parents { get { if (parents == null) { parents = new List (); } return parents; } } internal bool HasParent { get { return parents != null && parents.Count > 0; } } internal HierarchicalObject(Object theObject) { this.TheObject = theObject; } /// /// Add the parent if it is not exist in the parent list /// /// internal void AddUniqueParent(HierarchicalObject parent) { if (!Parents.Contains(parent)) { Parents.Add(parent); } } ////// Check to see if it has parent or not in a loop and update its parent's value /// internal void CheckParents() { if (HasParent) { Stackpath = new Stack (); Stack work = new Stack (); work.Push(this); path.Push(this); this.CheckParents(work, path); } } /// /// Check to see if it has parent or not in a loop and update its parent's value /// internal void CheckParents(Stackwork, Stack path) { if (!HasParent || (!object.ReferenceEquals(this, path.Peek()) && path.Contains(this))) { // Stop if there is no parent or it is in a loop // path.Peek() is always this, so we need to exclude it. // Debug.Assert(work.Count > 0 && path.Count > 0 && object.ReferenceEquals(path.Peek(), this)); HierarchicalObject topPath = path.Pop(); HierarchicalObject topWork = work.Pop(); while (work.Count > 0 && path.Count > 0 && object.ReferenceEquals(topPath, topWork)) { topPath = path.Pop(); topWork = work.Pop(); } if (topWork != topPath) { path.Push(topWork); topWork.CheckParents(work, path); } return; } else if (this.HasParent) { // has parent HierarchicalObject first = null; // find out all parents that is not in a loop and has lower priority then this // increase their priority and push them to the work stack, we need to walk up to the tree // one by one to update the grandparent's priority for (int i = Parents.Count - 1; i >= 0; i--) { HierarchicalObject current = Parents[i]; if (!path.Contains(current) && current.Height <= this.Height) { current.Height = this.Height + 1; Debug.Assert(current.Height < 1000); if (current.Height > 1000) { return; } work.Push(current); first = current; } } // Now we walk up the first parent if (first != null) { path.Push(first); first.CheckParents(work, path); } } } int IComparable .CompareTo(HierarchicalObject other) { return other.Height - this.Height; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- InternalCache.cs
- NullableFloatMinMaxAggregationOperator.cs
- NativeMethods.cs
- SolidColorBrush.cs
- DataSourceCollectionBase.cs
- PolicyLevel.cs
- ServicePointManager.cs
- ExpressionWriter.cs
- DelegateBodyWriter.cs
- XmlStreamStore.cs
- AnimationClockResource.cs
- ToolStripMenuItemCodeDomSerializer.cs
- RectangleGeometry.cs
- SafeRightsManagementHandle.cs
- OleDbParameterCollection.cs
- StrokeIntersection.cs
- EditorServiceContext.cs
- PictureBox.cs
- HtmlElementEventArgs.cs
- SQLGuid.cs
- HtmlMobileTextWriter.cs
- TcpAppDomainProtocolHandler.cs
- ClientCultureInfo.cs
- XamlTemplateSerializer.cs
- PartBasedPackageProperties.cs
- BorderGapMaskConverter.cs
- TimerElapsedEvenArgs.cs
- FixedSOMPageElement.cs
- PopupEventArgs.cs
- QueryOptionExpression.cs
- FileSystemEventArgs.cs
- basemetadatamappingvisitor.cs
- ItemsPresenter.cs
- ResourceManagerWrapper.cs
- OracleBinary.cs
- Task.cs
- ScriptControl.cs
- PropertyGridCommands.cs
- QueryCorrelationInitializer.cs
- ByteStack.cs
- PolyQuadraticBezierSegmentFigureLogic.cs
- XPathEmptyIterator.cs
- XsltInput.cs
- MethodResolver.cs
- SiteIdentityPermission.cs
- InternalControlCollection.cs
- AuthenticationModulesSection.cs
- Geometry.cs
- SqlSupersetValidator.cs
- SafeHandles.cs
- NoClickablePointException.cs
- TimeSpanValidator.cs
- indexingfiltermarshaler.cs
- CompensationDesigner.cs
- XmlDictionaryReader.cs
- UnsignedPublishLicense.cs
- RootBuilder.cs
- TransportConfigurationTypeElement.cs
- WebRequestModuleElement.cs
- AuthenticationException.cs
- GridViewUpdateEventArgs.cs
- DictionarySurrogate.cs
- RtfControls.cs
- DetailsViewRow.cs
- ProxyGenerationError.cs
- TimeSpanValidator.cs
- HttpProtocolImporter.cs
- EntityObject.cs
- HtmlInputFile.cs
- LinqDataSourceView.cs
- InvalidComObjectException.cs
- GeometryHitTestResult.cs
- LassoHelper.cs
- UnsafePeerToPeerMethods.cs
- CommonDialog.cs
- Point3DCollectionConverter.cs
- PageTheme.cs
- SafeNativeMethods.cs
- PersonalizationState.cs
- BinaryMessageEncodingBindingElement.cs
- KnownTypes.cs
- Dispatcher.cs
- AnnotationComponentChooser.cs
- ServiceChannelProxy.cs
- ObjectDataSourceSelectingEventArgs.cs
- Crc32.cs
- StreamGeometryContext.cs
- UnauthorizedWebPart.cs
- BulletDecorator.cs
- Floater.cs
- DynamicQueryStringParameter.cs
- StyleCollection.cs
- DataSourceXmlSerializationAttribute.cs
- ExpanderAutomationPeer.cs
- XPathAncestorQuery.cs
- DateTimeSerializationSection.cs
- GenericsNotImplementedException.cs
- ParentControlDesigner.cs
- CopyNamespacesAction.cs
- EarlyBoundInfo.cs