MemberProjectionIndex.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / MemberProjectionIndex.cs / 1305376 / MemberProjectionIndex.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Collections.Generic; 
using System.Text;
using System.Data.Common.Utils;
using System.Data.Common;
using System.Data.Mapping.ViewGeneration.Structures; 
using System.Diagnostics;
using System.Data.Metadata.Edm; 
 
namespace System.Data.Mapping.ViewGeneration.Structures
{ 

    /// Maps member paths to a dense space of integers, e.g., so that one can
    /// store memberpaths in arrays and use array indexes for easy and
    /// efficient handling 
    internal class MemberProjectionIndex : InternalBase
    { 
 
        #region Fields
        // A dictionary to get us from paths to indexes and an array for the 
        // other way around
        private Dictionary m_indexMap;
        private List m_members;
        #endregion 

 
        #region Constructor 
        // effects: Creates an empty map
        private MemberProjectionIndex() 
        {
            m_indexMap = new Dictionary(MemberPath.EqualityComparer);
            m_members = new List();
        } 
        #endregion
 
 
        #region MemberPathMapBase Properties
        // effects: See MemberPathMapBase.Count 
        internal int Count
        {
            get { return m_members.Count; }
        } 

        // effects: See MemberPathMapBase.indexer 
        internal MemberPath this[int index] 
        {
            get { return m_members[index]; } 
        }

        // effects: Returns the indexes of the key slots corresponding to
        // fields in this for which IsPartOfKey is true 
        internal IEnumerable KeySlots
        { 
            get 
            {
                List result = new List(); 
                for (int slotNum = 0; slotNum < Count; slotNum++)
                {
                    // We pass for numboolslots since we know that this is not a
                    // bool slot 
                    if (ProjectedSlot.IsKeySlot(slotNum, this, 0))
                    { 
                        result.Add(slotNum); 
                    }
                } 
                return result;
            }
        }
 
        // effects: returns an enumeration of all members
        internal IEnumerable Members 
        { 
            get { return m_members; }
        } 
        #endregion

        #region MemberPathMapBase Methods
        // effects: See MemberPathMapBase.IndexOf 
        internal int IndexOf(MemberPath member)
        { 
            int index; 
            if (m_indexMap.TryGetValue(member, out index))
            { 
                return index;
            }
            else
            { 
                return -1;
            } 
        } 
        #endregion
 
        #region Other Methods
        // effects: If an index already exists for member, this is a
        // noop. Else creates the next index available for member and returns it
        internal int CreateIndex(MemberPath member) 
        {
            int index; 
            if (false == m_indexMap.TryGetValue(member, out index)) 
            {
                index = m_indexMap.Count; 
                m_indexMap[member] = index;
                m_members.Add(member);
            }
            return index; 
        }
 
        internal override void ToCompactString(StringBuilder builder) 
        {
            builder.Append('<'); 
            StringUtil.ToCommaSeparatedString(builder, m_members);
            builder.Append('>');
        }
 
        #endregion
 
        #region Factory 

        // effects: Given an extent and the different condition members 
        // (e.g., isHighpriority, discriminator) that are used in the cells
        // for this extent, creates a SignatureGenerator object that is
        // capable of giving the signatures for the cells
        internal static MemberProjectionIndex Create(EntitySetBase extent, EdmItemCollection edmItemCollection) 
        {
            // We generate the indices for the projected slots as we traverse the metadata 
            MemberProjectionIndex index = new MemberProjectionIndex(); 

            MemberPath extentMember = new MemberPath(extent); 
            GatherPartialSignature(index, edmItemCollection, extentMember, false); // need not only keys
            return index;
        }
        #endregion 

 
        // requires: member is an Entity or Complex or Relation type 
        // effects: Starting at "member", generates the multiconstant signatures for
        // all the fields embedded in it. isNullable indicates if member can 
        // be nulled or not. needKeysOnly indicates whether we need to only
        // collect members that are keys.
        private static void GatherPartialSignature(MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, bool needKeysOnly)
        { 

            EdmType memberType = member.EdmType; 
            ComplexType complexTypemember = memberType as ComplexType; 
            Debug.Assert(complexTypemember != null ||
                         memberType is EntityType || // for entity sets 
                         memberType is AssociationType || // For relation sets
                         memberType is RefType, // for relation ends
                         "GatherPartialSignature only for complex types, entity sets, relationship ends");
 
            if (memberType is ComplexType && needKeysOnly)
            { 
                // Check if the complex type needs to be traversed or not. If not, just return 
                // from here. Else we need to continue to the code below. Right now, we do not
                // allow keys inside complex types 
                return;
            }

            // Make sure that this member is in the slot map before any of 
            // its embedded objects
            index.CreateIndex(member); 
 
            // Add the types can member have, i.e., its type and its subtypes
            List possibleTypes = new List(); 
            possibleTypes.AddRange(MetadataHelper.GetTypeAndSubtypesOf(memberType, edmItemCollection, false /*includeAbstractTypes*/));

            // Consider each possible type value -- each type value
            // conributes to a tuple in the result. For that possible type, 
            // add all the type members into the signature
            foreach (EdmType possibleType in possibleTypes) 
            { 
                // first, collect all scalar-typed members of this type in a signature
                GatherSignatureFromScalars(index, member, possibleType, needKeysOnly); 

                // Now drill down into complex-valued members and get a cross product of the existing signatures
                GatherSignaturesFromNonScalars(index, edmItemCollection,member, possibleType, needKeysOnly);
            } 
        }
 
        // requires: possibleType is the member's type or one of its subtypes 
        // possibleType is a StructuralType
        // effects: Given a member and the corresponding possible type 
        // that it can take, determine the attributes that are relevant
        // for this possibleType and returns a multiconstant signature
        // corresponding to this possibleType and the attributes. If only
        // keys are needed, collect the key fields only. memberSlotId 
        // indicates the slot number allocated for member in the multiconstant
        private static void GatherSignatureFromScalars(MemberProjectionIndex index, MemberPath member, EdmType possibleType, bool needKeysOnly) 
        { 
            // For each child member of this type, collect all the relevant scalar fields
            StructuralType structuralType = (StructuralType)possibleType; ; 
 	    foreach (EdmMember childMetadata in structuralType.Members)
            {
                if (!Helper.IsEdmProperty(childMetadata))
                { 
                    // We only care about properties. Associations Ends are
                    // captured in NonScalars really 
                    continue; 
                }
                EdmProperty childProperty = (EdmProperty)childMetadata; 

                // Collect all scalar-typed members of this type
                // if needKeysOnly, collect only keys
 
                if (MetadataHelper.IsNonRefSimpleMember(childProperty) &&
                    (!needKeysOnly || MetadataHelper.IsPartOfEntityTypeKey(childProperty))) 
                { 
                    MemberPath scalarMember = new MemberPath(member, childMetadata);
                    // Note: scalarMember's parent has already been added to the projectedSlotMap 
                    index.CreateIndex(scalarMember);
                }
            }
        } 

        // requires: possibleType is the member's type or one of its subtypes 
        // effects: Given a member and the corresponding possible type that 
        // it can be, computes a cross-product of initial signature with the
        // different types that can occur inside possibleType 
        private static void GatherSignaturesFromNonScalars(MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, EdmType possibleType, bool needKeysOnly)
        {

            int childNumber = 0; 

            // Go through all the members for the complex type while ignoring scalars 
            foreach (EdmMember childMember in Helper.GetAllStructuralMembers(possibleType)) 
            {
                childNumber++; 
                if (MetadataHelper.IsNonRefSimpleMember(childMember))
                {
                    continue;
                } 

                Debug.Assert(childMember.TypeUsage.EdmType is ComplexType || 
                             childMember.TypeUsage.EdmType is RefType, // for relation ends 
                             "Only non-scalars currently handled -- complex types, relationship ends");
 
                // Only keys are required for entities hanging off relation ends of an association
                // or for the first end of composition
                needKeysOnly = needKeysOnly || (childMember is AssociationEndMember);
 
                MemberPath nonScalarMember = new MemberPath(member, childMember);
                GatherPartialSignature(index, edmItemCollection, nonScalarMember, needKeysOnly); 
            } 
        }
 



    } 

} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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