TableAdapterManagerHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

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); 

            List selfRefs = 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) { 
                    Stack path = 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(Stack work, 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

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK