DefaultObjectMappingItemCollection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Mapping / DefaultObjectMappingItemCollection.cs / 1 / DefaultObjectMappingItemCollection.cs

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

using System; 
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Xml.XPath; 
using System.Xml;
using System.Xml.Schema; 
using System.Data.Metadata.Edm; 
using System.Data.Entity;
 
namespace System.Data.Mapping {
    /// 
    /// The class creates a default OCMapping between a TypeMetadata in O space
    /// and an TypeMetadata in Edm space. The loader expects that for each member in 
    /// C space type there exists a member in O space type that has the same name. The member maps will be stored in
    /// C space member order. 
    ///  
    internal class DefaultObjectMappingItemCollection : MappingItemCollection {
        #region Constructors 
        /// 
        /// Constrcutor to create an instance of DefaultObjectMappingItemCollection.
        /// To start with we will create a Schema under which maps will be created.
        ///  
        /// 
        ///  
        public DefaultObjectMappingItemCollection(EdmItemCollection edmCollection, 
            ObjectItemCollection objectCollection) : base(DataSpace.OCSpace)
        { 
            EntityUtil.CheckArgumentNull(edmCollection, "edmCollection");
            EntityUtil.CheckArgumentNull(objectCollection, "objectCollection");
            this.m_edmCollection = edmCollection;
            this.m_objectCollection = objectCollection; 
            LoadPrimitiveMaps();
        } 
        #endregion 

        #region Fields 
        private ObjectItemCollection m_objectCollection;
        private EdmItemCollection m_edmCollection;
        private Dictionary clrTypeIndexes = new Dictionary(StringComparer.Ordinal); //Indexes into the type mappings collection based on clr type name
        private Dictionary cdmTypeIndexes = new Dictionary(StringComparer.Ordinal); //Indexes into the type mappings collection based on clr type name 
        #endregion
 
        #region Methods 
        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        /// true for case-insensitive lookup 
        ///  Thrown if mapping space is not valid
        internal override Map GetMap(string identity, DataSpace typeSpace, bool ignoreCase) 
        { 
            Map map;
            if (!this.TryGetMap(identity, typeSpace, ignoreCase, out map)) 
            {
                throw new InvalidOperationException(System.Data.Entity.Strings.Mapping_Object_InvalidType(identity));
            }
            return map; 
        }
 
        ///  
        /// Search for a Mapping metadata with the specified type key.
        ///  
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        /// true for case-insensitive lookup
        ///  
        /// Returns false if no match found.
        internal override bool TryGetMap(string identity, DataSpace typeSpace, bool ignoreCase, out Map map) 
        { 
            EdmType cdmType = null;
            EdmType clrType = null; 
            if (typeSpace == DataSpace.CSpace)
            {
                if (ignoreCase)
                { 
                    // Get the correct casing of the identity first if we are asked to do ignore case
                    if (!m_edmCollection.TryGetItem(identity, true, out cdmType)) 
                    { 
                        map = null;
                        return false; 
                    }

                    identity = cdmType.Identity;
                } 

                int index; 
                if (cdmTypeIndexes.TryGetValue(identity, out index)) 
                {
                    map = (Map)this[index]; 
                    return true;
                }

                if (cdmType != null || 
                    m_edmCollection.TryGetItem(identity, ignoreCase, out cdmType))
                { 
                    // If the mapping is not already loaded, then get the mapping ospace type 
                    m_objectCollection.TryGetOSpaceType(cdmType, out clrType);
                } 
            }
            else if (typeSpace == DataSpace.OSpace)
            {
                if (ignoreCase) 
                {
                    // Get the correct casing of the identity first if we are asked to do ignore case 
                    if (!m_objectCollection.TryGetItem(identity, true, out clrType)) 
                    {
                        map = null; 
                        return false;
                    }

                    identity = clrType.Identity; 
                }
 
                int index; 
                if (clrTypeIndexes.TryGetValue(identity, out index))
                { 
                    map = (Map)this[index];
                    return true;
                }
 
                if (clrType != null ||
                    m_objectCollection.TryGetItem(identity, ignoreCase, out clrType)) 
                { 
                    // If the mapping is not already loaded, get the mapping cspace type
                    string cspaceTypeName = ObjectItemCollection.TryGetMappingCSpaceTypeIdentity(clrType); 
                    m_edmCollection.TryGetItem(cspaceTypeName, out cdmType);
                }
            }
 
            if ((clrType == null) || (cdmType == null))
            { 
                map = null; 
                return false;
            } 
            else
            {
                map = this.GetDefaultMapping(cdmType, clrType);
                return true; 
            }
        } 
 
        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        ///  Thrown if mapping space is not valid 
        internal override Map GetMap(string identity, DataSpace typeSpace)
        { 
            return this.GetMap(identity, typeSpace, false /*ignoreCase*/); 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// identity of the type 
        /// The dataspace that the type for which map needs to be returned belongs to
        ///  
        /// Returns false if no match found. 
        internal override bool TryGetMap(string identity, DataSpace typeSpace, out Map map)
        { 
            return this.TryGetMap(identity, typeSpace, false /*ignoreCase*/, out map);
        }

        ///  
        /// Search for a Mapping metadata with the specified type key.
        ///  
        ///  
        internal override Map GetMap(GlobalItem item)
        { 
            EntityUtil.CheckArgumentNull(item, "item");
            Map map;
            if (!this.TryGetMap(item, out map))
            { 
                throw new InvalidOperationException(System.Data.Entity.Strings.Mapping_Object_InvalidType(item.Identity));
            } 
            return map; 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        ///  
        /// 
        /// Returns false if no match found. 
        internal override bool TryGetMap(GlobalItem item, out Map map) 
        {
            if (item == null) 
            {
                map = null;
                return false;
            } 

            DataSpace typeSpace = item.DataSpace; 
 
            //For transient types just create a map on fly and return
            EdmType edmType = item as EdmType; 
            if (edmType != null)
            {
                if (Helper.IsTransientType(edmType))
                { 
                    map = GetOCMapForTransientType(edmType, typeSpace);
                    if (map != null) 
                    { 
                        return true;
                    } 
                    else
                    {
                        return false;
                    } 
                }
            } 
            return this.TryGetMap(item.Identity, typeSpace, out map); 
        }
 
        /// 
        /// The method creates a default mapping between two TypeMetadatas - one in
        /// C space and one in O space. The precondition for calling this method is that
        /// the type in Object space contains the members with the same name as those of defined in 
        /// C space. It is not required the otherway.
        ///  
        ///  
        /// 
        private Map GetDefaultMapping(EdmType cdmType, EdmType clrType) { 
            Debug.Assert((cdmType != null) && (clrType != null));
            return LoadObjectMapping(cdmType, clrType, this);
        }
 
        private Map GetOCMapForTransientType(EdmType edmType, DataSpace typeSpace)
        { 
            Debug.Assert(typeSpace == DataSpace.CSpace || typeSpace == DataSpace.OSpace || Helper.IsRowType(edmType) || Helper.IsCollectionType(edmType)); 
            EdmType clrType = null;
            EdmType cdmType = null; 
            int index = -1;
            if (typeSpace != DataSpace.OSpace)
            {
                if (cdmTypeIndexes.TryGetValue(edmType.Identity, out index)) 
                {
                    return (Map)this[index]; 
                } 
                else
                { 
                    cdmType = edmType;
                    clrType = ConvertCSpaceToOSpaceType(edmType);
                }
            } 
            else if (typeSpace == DataSpace.OSpace)
            { 
                if (clrTypeIndexes.TryGetValue(edmType.Identity, out index)) 
                {
                    return (Map)this[index]; 
                }
                else
                {
                    clrType = edmType; 
                    cdmType = ConvertOSpaceToCSpaceType(clrType);
                } 
            } 

            ObjectTypeMapping typeMapping = new ObjectTypeMapping(clrType, cdmType); 
            if (BuiltInTypeKind.RowType == edmType.BuiltInTypeKind)
            {
                RowType clrRowType = (RowType)clrType;
                RowType edmRowType = (RowType)cdmType; 

                Debug.Assert(clrRowType.Properties.Count == edmRowType.Properties.Count, "Property count mismatch"); 
                for (int idx = 0; idx < clrRowType.Properties.Count; idx++) 
                {
                    typeMapping.AddMemberMap(new ObjectPropertyMapping(edmRowType.Properties[idx], clrRowType.Properties[idx])); 
                }
            }
            if ( (!cdmTypeIndexes.ContainsKey(cdmType.Identity)) && (!clrTypeIndexes.ContainsKey(clrType.Identity)) )
            { 
            AddInternalMapping(typeMapping);
            } 
            return typeMapping; 
        }
 
        /// Convert CSpace TypeMetadata into OSpace TypeMetadata
        /// 
        /// OSpace type metadata
        private EdmType ConvertCSpaceToOSpaceType(EdmType cdmType) 
        {
            EdmType clrType = null; 
 
            if (Helper.IsCollectionType(cdmType))
            { 
                EdmType elemType = ConvertCSpaceToOSpaceType(((CollectionType)cdmType).TypeUsage.EdmType);
                clrType = new CollectionType(elemType);
            }
            else if (Helper.IsRowType(cdmType)) 
            {
                List clrProperties = new List(); 
                foreach (EdmProperty column in ((RowType)cdmType).Properties) 
                {
                    EdmType clrPropertyType = ConvertCSpaceToOSpaceType(column.TypeUsage.EdmType); 
                    EdmProperty clrProperty = new EdmProperty(column.Name, TypeUsage.Create(clrPropertyType));
                    clrProperties.Add(clrProperty);
                }
                clrType = new RowType(clrProperties, ((RowType)cdmType).InitializerMetadata); 
            }
            else if (Helper.IsRefType(cdmType)) 
            { 
                clrType = new RefType((EntityType)ConvertCSpaceToOSpaceType(((RefType)cdmType).ElementType));
            } 
            else if (Helper.IsPrimitiveType(cdmType))
            {
                clrType = m_objectCollection.GetMappedPrimitiveType(((PrimitiveType)cdmType).PrimitiveTypeKind);
            } 
            else
            { 
                clrType = ((ObjectTypeMapping)GetMap(cdmType)).ClrType; 
            }
            Debug.Assert((null != clrType), "null converted clr type"); 
            return clrType;
        }

        /// Convert CSpace TypeMetadata into OSpace TypeMetadata 
        /// 
        /// OSpace type metadata 
        private EdmType ConvertOSpaceToCSpaceType(EdmType clrType) 
        {
            EdmType cdmType = null; 

            if (Helper.IsCollectionType(clrType))
            {
                EdmType elemType = ConvertOSpaceToCSpaceType(((CollectionType)clrType).TypeUsage.EdmType); 
                cdmType = new CollectionType(elemType);
            } 
            else if (Helper.IsRowType(clrType)) 
            {
                List cdmProperties = new List(); 
                foreach (EdmProperty column in ((RowType)clrType).Properties)
                {
                    EdmType cdmPropertyType = ConvertOSpaceToCSpaceType(column.TypeUsage.EdmType);
                    EdmProperty cdmPorperty = new EdmProperty(column.Name, TypeUsage.Create(cdmPropertyType)); 
                    cdmProperties.Add(cdmPorperty);
                } 
                cdmType = new RowType(cdmProperties, ((RowType)clrType).InitializerMetadata); 
            }
            else if (Helper.IsRefType(clrType)) 
            {
                cdmType = new RefType((EntityType)(ConvertOSpaceToCSpaceType(((RefType)clrType).ElementType)));
            }
            else 
            {
                cdmType = ((ObjectTypeMapping)GetMap(clrType)).EdmType; 
            } 
            Debug.Assert((null != cdmType), "null converted clr type");
            return cdmType; 
        }

        /// 
        /// checks if the schemaKey refers to the primitive OC mapping schema and if true, 
        /// loads the maps between primitive types
        ///  
        /// returns the loaded schema if the schema key refers to a primitive schema 
        private void LoadPrimitiveMaps() {
            // Get all the primitive types from the CSpace and create OCMaps for it 
            IEnumerable cspaceTypes = m_edmCollection.GetPrimitiveTypes();
            foreach (PrimitiveType type in cspaceTypes)
            {
                PrimitiveType ospaceType = m_objectCollection.GetMappedPrimitiveType(type.PrimitiveTypeKind); 
                Debug.Assert(ospaceType != null, "all primitive type must have been loaded");
                this.AddInternalMapping(new ObjectTypeMapping(ospaceType, type)); 
            } 
        }
 
        // Add to the cache. If it is already present, then throw an exception
        private void AddInternalMapping(ObjectTypeMapping objectMap)
        {
            string clrName = objectMap.ClrType.Identity; 
            string cdmName = objectMap.EdmType.Identity;
            int currIndex = this.Count; 
            //Always assume that the first Map for an associated map being added is 
            //the default map for primitive type. Similarly, row and collection types can collide
            //because their components are primitive types. For other types, 
            //there should be only one map
            if (clrTypeIndexes.ContainsKey(clrName))
            {
                if (BuiltInTypeKind.PrimitiveType != objectMap.ClrType.BuiltInTypeKind && 
                    BuiltInTypeKind.RowType != objectMap.ClrType.BuiltInTypeKind &&
                    BuiltInTypeKind.CollectionType != objectMap.ClrType.BuiltInTypeKind) 
                { 
                    throw new MappingException(System.Data.Entity.Strings.Mapping_Duplicate_Type_1(clrName));
                } 
            }
            else
            {
                clrTypeIndexes.Add(clrName, currIndex); 
            }
            if (cdmTypeIndexes.ContainsKey(cdmName)) 
            { 
                if (BuiltInTypeKind.PrimitiveType != objectMap.EdmType.BuiltInTypeKind &&
                    BuiltInTypeKind.RowType != objectMap.EdmType.BuiltInTypeKind && 
                    BuiltInTypeKind.CollectionType != objectMap.EdmType.BuiltInTypeKind)
                {
                    throw new MappingException(System.Data.Entity.Strings.Mapping_Duplicate_Type_1(clrName));
                } 
            }
            else 
            { 
                cdmTypeIndexes.Add(cdmName, currIndex);
            } 
            objectMap.DataSpace = DataSpace.OCSpace;
            base.AddInternal (objectMap);
        }
 
        /// 
        /// The method fills up the children of ObjectMapping. It goes through the 
        /// members in CDM type and finds the member in Object space with the same name 
        /// and creates a member map between them. These member maps are added
        /// as children of the object mapping. 
        /// 
        /// 
        /// 
        ///  
        internal static ObjectTypeMapping LoadObjectMapping(EdmType cdmType, EdmType objectType, DefaultObjectMappingItemCollection ocItemCollection)
        { 
            Dictionary typeMappings = new Dictionary(StringComparer.Ordinal); 
            ObjectTypeMapping typeMapping = LoadObjectMapping(cdmType, objectType, ocItemCollection, typeMappings);
 
            // If DefaultOCMappingItemCollection is not null, add all the type mappings to the item collection
            if (ocItemCollection != null)
            {
                foreach (ObjectTypeMapping map in typeMappings.Values) 
                {
                    ocItemCollection.AddInternalMapping(map); 
                } 
            }
 
            return typeMapping;
        }

        private static ObjectTypeMapping LoadObjectMapping(EdmType edmType, EdmType objectType, DefaultObjectMappingItemCollection ocItemCollection, 
            Dictionary typeMappings)
        { 
            Debug.Assert((edmType != null) && (objectType != null)); 
            Debug.Assert((edmType.BuiltInTypeKind == objectType.BuiltInTypeKind), "The BuiltInTypeKind must be same in LoadObjectMapping");
 
            // Check if both the types are abstract or both of them are not
            if (edmType.Abstract != objectType.Abstract)
            {
                throw new MappingException(System.Data.Entity.Strings.Mapping_AbstractTypeMappingToNonAbstractType(edmType.FullName, objectType.FullName)); 
            }
 
            ObjectTypeMapping objectTypeMapping = new ObjectTypeMapping(objectType, edmType); 
            typeMappings.Add(edmType.FullName, objectTypeMapping);
 
            if (edmType.BuiltInTypeKind == BuiltInTypeKind.EntityType || edmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType)
            {
                LoadEntityTypeOrComplexTypeMapping(objectTypeMapping, edmType, objectType, ocItemCollection, typeMappings);
            } 
            else
            { 
                LoadAssociationTypeMapping(objectTypeMapping, edmType, objectType, ocItemCollection, typeMappings); 
            }
 
            return objectTypeMapping;
        }

        ///  
        /// Tries and get the mapping ospace member for the given edmMember and the ospace type
        ///  
        ///  
        /// 
        ///  
        /// Validates the scalar property on the cspace side and ospace side and creates a new
        /// ObjectPropertyMapping, if everything maps property
        /// 
        ///  
        /// 
        ///  
        private static ObjectPropertyMapping LoadScalarPropertyMapping(EdmProperty edmProperty, EdmProperty objectProperty) 
        {
            Debug.Assert(Helper.IsPrimitiveType(edmProperty.TypeUsage.EdmType), "Only edm scalar properties expected"); 
            Debug.Assert(Helper.IsPrimitiveType(objectProperty.TypeUsage.EdmType), "Only object scalar properties expected");

            return new ObjectPropertyMapping(edmProperty, objectProperty);
        } 

        ///  
        /// Load the entity type or complex type mapping 
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        private static void LoadEntityTypeOrComplexTypeMapping(ObjectTypeMapping objectMapping, EdmType edmType, EdmType objectType,
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary typeMappings) 
        { 
            Debug.Assert(edmType.BuiltInTypeKind == BuiltInTypeKind.EntityType ||
                    edmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, 
                    "Expected Type Encountered in LoadEntityTypeOrComplexTypeMapping");
            Debug.Assert((edmType.BuiltInTypeKind == objectType.BuiltInTypeKind), "The BuiltInTypeKind must be same in LoadEntityTypeOrComplexTypeMapping");

            StructuralType cdmStructuralType = (StructuralType)edmType; 
            StructuralType objectStructuralType = (StructuralType)objectType;
 
            if (cdmStructuralType.Members.Count != objectStructuralType.Members.Count) 
            {
                throw new MappingException(System.Data.Entity.Strings.Mapping_Default_OCMapping_Member_Count_Mismatch_2( 
                          edmType.FullName, objectType.FullName));
            }

            //Go through the CDMMembers and find the corresponding member in Object space 
            //and create a member map.
            foreach (EdmMember edmMember in cdmStructuralType.Members) 
            { 
                EdmMember objectMember = GetObjectMember(edmMember, objectStructuralType);
 
                if (Helper.IsEdmProperty(edmMember))
                {
                    EdmProperty edmPropertyMember = (EdmProperty)edmMember;
                    EdmProperty edmPropertyObject = (EdmProperty)objectMember; 

                    //Depending on the type of member load the member mapping i.e. For complex 
                    //members we have to go in and load the child members of the Complex type. 
                    if (Helper.IsComplexType(edmMember.TypeUsage.EdmType))
                    { 
                        objectMapping.AddMemberMap(
                            LoadComplexMemberMapping(edmPropertyMember, edmPropertyObject, ocItemCollection, typeMappings));
                    }
                    else 
                    {
                        objectMapping.AddMemberMap( 
                            LoadScalarPropertyMapping(edmPropertyMember, edmPropertyObject)); 
                    }
                } 
                else
                {
                    Debug.Assert(edmMember.BuiltInTypeKind == BuiltInTypeKind.NavigationProperty, "Unexpected Property type encountered");
 
                    // For navigation properties, we need to make sure the relationship type on the navigation property is mapped
                    NavigationProperty navigationProperty = (NavigationProperty)edmMember; 
                    NavigationProperty objectNavigationProperty = (NavigationProperty)objectMember; 
                    LoadTypeMapping(navigationProperty.RelationshipType, objectNavigationProperty.RelationshipType, ocItemCollection, typeMappings);
 
                    objectMapping.AddMemberMap(new ObjectNavigationPropertyMapping(navigationProperty, objectNavigationProperty));
                }
            }
        } 

        ///  
        /// Loads Association Type Mapping 
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        private static void LoadAssociationTypeMapping(ObjectTypeMapping objectMapping, EdmType edmType, EdmType objectType,
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary typeMappings) 
        { 
            Debug.Assert(edmType.BuiltInTypeKind == BuiltInTypeKind.AssociationType, "Expected Type Encountered in LoadAssociationTypeMapping");
            Debug.Assert((edmType.BuiltInTypeKind == objectType.BuiltInTypeKind), "The BuiltInTypeKind must be same in LoadAssociationTypeMapping"); 

            AssociationType association = (AssociationType)edmType;
            AssociationType objectAssociation = (AssociationType)objectType;
 
            foreach (AssociationEndMember edmEnd in association.AssociationEndMembers)
            { 
                AssociationEndMember objectEnd = (AssociationEndMember)GetObjectMember(edmEnd, objectAssociation); 

                if (edmEnd.RelationshipMultiplicity != objectEnd.RelationshipMultiplicity) 
                {
                    throw new MappingException(System.Data.Entity.Strings.Mapping_Default_OCMapping_MultiplicityMismatch_6(
                        edmEnd.RelationshipMultiplicity, edmEnd.Name, association.FullName,
                        objectEnd.RelationshipMultiplicity, objectEnd.Name, objectAssociation.FullName)); 
                }
 
                Debug.Assert(edmEnd.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.RefType, "Ends must be of Ref type"); 

                // GetMap for the entity types for the ends of the relationship type to make sure 
                // the entity type mentioned are valid
                LoadTypeMapping(((RefType)edmEnd.TypeUsage.EdmType).ElementType,
                                ((RefType)objectEnd.TypeUsage.EdmType).ElementType, ocItemCollection, typeMappings);
 
                objectMapping.AddMemberMap(new ObjectAssociationEndMapping(edmEnd, objectEnd));
            } 
        } 

        ///  
        /// The method loads the EdmMember mapping for complex members.
        /// It goes through the CDM members of the Complex Cdm type and
        /// tries to find the corresponding members in Complex Clr type.
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        private static ObjectComplexPropertyMapping LoadComplexMemberMapping(EdmProperty containingEdmMember, EdmProperty containingClrMember,
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary typeMappings)
        {
            Debug.Assert(containingEdmMember.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, "edm member declaringType must be of complexType"); 
            Debug.Assert(containingClrMember.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, "clr member declaringType must be of complexType");
 
            ComplexType edmComplexType = (ComplexType)containingEdmMember.TypeUsage.EdmType; 
            ComplexType objectComplexType = (ComplexType)containingClrMember.TypeUsage.EdmType;
 
            // Get the type mapping for the complex type
            ObjectTypeMapping complexTypeMapping = LoadTypeMapping(edmComplexType, objectComplexType, ocItemCollection, typeMappings);

            //Go through the CDMMembers and find the corresponding member in Object space 
            //and create a member map.
            return new ObjectComplexPropertyMapping(containingEdmMember, containingClrMember, complexTypeMapping); 
        } 

        private static ObjectTypeMapping LoadTypeMapping(EdmType edmType, EdmType objectType, 
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary typeMappings)
        {
            ObjectTypeMapping objectTypeMapping;
 
            //First, check in the type mappings to find out if the mapping is already present
            if (typeMappings.TryGetValue(edmType.FullName, out objectTypeMapping)) 
            { 
                return objectTypeMapping;
            } 

            if (ocItemCollection != null)
            {
                ObjectTypeMapping typeMapping; 

                if (ocItemCollection.ContainsMap(edmType, out typeMapping)) 
                { 
                    return (ObjectTypeMapping)typeMapping;
                } 
            }

            // If the type mapping is not already loaded, then load it
            return LoadObjectMapping(edmType, objectType, ocItemCollection, typeMappings); 
        }
 
        private bool ContainsMap(GlobalItem cspaceItem, out ObjectTypeMapping map) 
        {
            Debug.Assert(cspaceItem.DataSpace == DataSpace.CSpace, "ContainsMap: It must be a CSpace item"); 
            int index;
            if (cdmTypeIndexes.TryGetValue(cspaceItem.Identity, out index))
            {
                map = (ObjectTypeMapping)this[index]; 
                return true;
            } 
 
            map = null;
            return false; 
        }

        #endregion
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Xml.XPath; 
using System.Xml;
using System.Xml.Schema; 
using System.Data.Metadata.Edm; 
using System.Data.Entity;
 
namespace System.Data.Mapping {
    /// 
    /// The class creates a default OCMapping between a TypeMetadata in O space
    /// and an TypeMetadata in Edm space. The loader expects that for each member in 
    /// C space type there exists a member in O space type that has the same name. The member maps will be stored in
    /// C space member order. 
    ///  
    internal class DefaultObjectMappingItemCollection : MappingItemCollection {
        #region Constructors 
        /// 
        /// Constrcutor to create an instance of DefaultObjectMappingItemCollection.
        /// To start with we will create a Schema under which maps will be created.
        ///  
        /// 
        ///  
        public DefaultObjectMappingItemCollection(EdmItemCollection edmCollection, 
            ObjectItemCollection objectCollection) : base(DataSpace.OCSpace)
        { 
            EntityUtil.CheckArgumentNull(edmCollection, "edmCollection");
            EntityUtil.CheckArgumentNull(objectCollection, "objectCollection");
            this.m_edmCollection = edmCollection;
            this.m_objectCollection = objectCollection; 
            LoadPrimitiveMaps();
        } 
        #endregion 

        #region Fields 
        private ObjectItemCollection m_objectCollection;
        private EdmItemCollection m_edmCollection;
        private Dictionary clrTypeIndexes = new Dictionary(StringComparer.Ordinal); //Indexes into the type mappings collection based on clr type name
        private Dictionary cdmTypeIndexes = new Dictionary(StringComparer.Ordinal); //Indexes into the type mappings collection based on clr type name 
        #endregion
 
        #region Methods 
        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        /// true for case-insensitive lookup 
        ///  Thrown if mapping space is not valid
        internal override Map GetMap(string identity, DataSpace typeSpace, bool ignoreCase) 
        { 
            Map map;
            if (!this.TryGetMap(identity, typeSpace, ignoreCase, out map)) 
            {
                throw new InvalidOperationException(System.Data.Entity.Strings.Mapping_Object_InvalidType(identity));
            }
            return map; 
        }
 
        ///  
        /// Search for a Mapping metadata with the specified type key.
        ///  
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        /// true for case-insensitive lookup
        ///  
        /// Returns false if no match found.
        internal override bool TryGetMap(string identity, DataSpace typeSpace, bool ignoreCase, out Map map) 
        { 
            EdmType cdmType = null;
            EdmType clrType = null; 
            if (typeSpace == DataSpace.CSpace)
            {
                if (ignoreCase)
                { 
                    // Get the correct casing of the identity first if we are asked to do ignore case
                    if (!m_edmCollection.TryGetItem(identity, true, out cdmType)) 
                    { 
                        map = null;
                        return false; 
                    }

                    identity = cdmType.Identity;
                } 

                int index; 
                if (cdmTypeIndexes.TryGetValue(identity, out index)) 
                {
                    map = (Map)this[index]; 
                    return true;
                }

                if (cdmType != null || 
                    m_edmCollection.TryGetItem(identity, ignoreCase, out cdmType))
                { 
                    // If the mapping is not already loaded, then get the mapping ospace type 
                    m_objectCollection.TryGetOSpaceType(cdmType, out clrType);
                } 
            }
            else if (typeSpace == DataSpace.OSpace)
            {
                if (ignoreCase) 
                {
                    // Get the correct casing of the identity first if we are asked to do ignore case 
                    if (!m_objectCollection.TryGetItem(identity, true, out clrType)) 
                    {
                        map = null; 
                        return false;
                    }

                    identity = clrType.Identity; 
                }
 
                int index; 
                if (clrTypeIndexes.TryGetValue(identity, out index))
                { 
                    map = (Map)this[index];
                    return true;
                }
 
                if (clrType != null ||
                    m_objectCollection.TryGetItem(identity, ignoreCase, out clrType)) 
                { 
                    // If the mapping is not already loaded, get the mapping cspace type
                    string cspaceTypeName = ObjectItemCollection.TryGetMappingCSpaceTypeIdentity(clrType); 
                    m_edmCollection.TryGetItem(cspaceTypeName, out cdmType);
                }
            }
 
            if ((clrType == null) || (cdmType == null))
            { 
                map = null; 
                return false;
            } 
            else
            {
                map = this.GetDefaultMapping(cdmType, clrType);
                return true; 
            }
        } 
 
        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        ///  Thrown if mapping space is not valid 
        internal override Map GetMap(string identity, DataSpace typeSpace)
        { 
            return this.GetMap(identity, typeSpace, false /*ignoreCase*/); 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// identity of the type 
        /// The dataspace that the type for which map needs to be returned belongs to
        ///  
        /// Returns false if no match found. 
        internal override bool TryGetMap(string identity, DataSpace typeSpace, out Map map)
        { 
            return this.TryGetMap(identity, typeSpace, false /*ignoreCase*/, out map);
        }

        ///  
        /// Search for a Mapping metadata with the specified type key.
        ///  
        ///  
        internal override Map GetMap(GlobalItem item)
        { 
            EntityUtil.CheckArgumentNull(item, "item");
            Map map;
            if (!this.TryGetMap(item, out map))
            { 
                throw new InvalidOperationException(System.Data.Entity.Strings.Mapping_Object_InvalidType(item.Identity));
            } 
            return map; 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        ///  
        /// 
        /// Returns false if no match found. 
        internal override bool TryGetMap(GlobalItem item, out Map map) 
        {
            if (item == null) 
            {
                map = null;
                return false;
            } 

            DataSpace typeSpace = item.DataSpace; 
 
            //For transient types just create a map on fly and return
            EdmType edmType = item as EdmType; 
            if (edmType != null)
            {
                if (Helper.IsTransientType(edmType))
                { 
                    map = GetOCMapForTransientType(edmType, typeSpace);
                    if (map != null) 
                    { 
                        return true;
                    } 
                    else
                    {
                        return false;
                    } 
                }
            } 
            return this.TryGetMap(item.Identity, typeSpace, out map); 
        }
 
        /// 
        /// The method creates a default mapping between two TypeMetadatas - one in
        /// C space and one in O space. The precondition for calling this method is that
        /// the type in Object space contains the members with the same name as those of defined in 
        /// C space. It is not required the otherway.
        ///  
        ///  
        /// 
        private Map GetDefaultMapping(EdmType cdmType, EdmType clrType) { 
            Debug.Assert((cdmType != null) && (clrType != null));
            return LoadObjectMapping(cdmType, clrType, this);
        }
 
        private Map GetOCMapForTransientType(EdmType edmType, DataSpace typeSpace)
        { 
            Debug.Assert(typeSpace == DataSpace.CSpace || typeSpace == DataSpace.OSpace || Helper.IsRowType(edmType) || Helper.IsCollectionType(edmType)); 
            EdmType clrType = null;
            EdmType cdmType = null; 
            int index = -1;
            if (typeSpace != DataSpace.OSpace)
            {
                if (cdmTypeIndexes.TryGetValue(edmType.Identity, out index)) 
                {
                    return (Map)this[index]; 
                } 
                else
                { 
                    cdmType = edmType;
                    clrType = ConvertCSpaceToOSpaceType(edmType);
                }
            } 
            else if (typeSpace == DataSpace.OSpace)
            { 
                if (clrTypeIndexes.TryGetValue(edmType.Identity, out index)) 
                {
                    return (Map)this[index]; 
                }
                else
                {
                    clrType = edmType; 
                    cdmType = ConvertOSpaceToCSpaceType(clrType);
                } 
            } 

            ObjectTypeMapping typeMapping = new ObjectTypeMapping(clrType, cdmType); 
            if (BuiltInTypeKind.RowType == edmType.BuiltInTypeKind)
            {
                RowType clrRowType = (RowType)clrType;
                RowType edmRowType = (RowType)cdmType; 

                Debug.Assert(clrRowType.Properties.Count == edmRowType.Properties.Count, "Property count mismatch"); 
                for (int idx = 0; idx < clrRowType.Properties.Count; idx++) 
                {
                    typeMapping.AddMemberMap(new ObjectPropertyMapping(edmRowType.Properties[idx], clrRowType.Properties[idx])); 
                }
            }
            if ( (!cdmTypeIndexes.ContainsKey(cdmType.Identity)) && (!clrTypeIndexes.ContainsKey(clrType.Identity)) )
            { 
            AddInternalMapping(typeMapping);
            } 
            return typeMapping; 
        }
 
        /// Convert CSpace TypeMetadata into OSpace TypeMetadata
        /// 
        /// OSpace type metadata
        private EdmType ConvertCSpaceToOSpaceType(EdmType cdmType) 
        {
            EdmType clrType = null; 
 
            if (Helper.IsCollectionType(cdmType))
            { 
                EdmType elemType = ConvertCSpaceToOSpaceType(((CollectionType)cdmType).TypeUsage.EdmType);
                clrType = new CollectionType(elemType);
            }
            else if (Helper.IsRowType(cdmType)) 
            {
                List clrProperties = new List(); 
                foreach (EdmProperty column in ((RowType)cdmType).Properties) 
                {
                    EdmType clrPropertyType = ConvertCSpaceToOSpaceType(column.TypeUsage.EdmType); 
                    EdmProperty clrProperty = new EdmProperty(column.Name, TypeUsage.Create(clrPropertyType));
                    clrProperties.Add(clrProperty);
                }
                clrType = new RowType(clrProperties, ((RowType)cdmType).InitializerMetadata); 
            }
            else if (Helper.IsRefType(cdmType)) 
            { 
                clrType = new RefType((EntityType)ConvertCSpaceToOSpaceType(((RefType)cdmType).ElementType));
            } 
            else if (Helper.IsPrimitiveType(cdmType))
            {
                clrType = m_objectCollection.GetMappedPrimitiveType(((PrimitiveType)cdmType).PrimitiveTypeKind);
            } 
            else
            { 
                clrType = ((ObjectTypeMapping)GetMap(cdmType)).ClrType; 
            }
            Debug.Assert((null != clrType), "null converted clr type"); 
            return clrType;
        }

        /// Convert CSpace TypeMetadata into OSpace TypeMetadata 
        /// 
        /// OSpace type metadata 
        private EdmType ConvertOSpaceToCSpaceType(EdmType clrType) 
        {
            EdmType cdmType = null; 

            if (Helper.IsCollectionType(clrType))
            {
                EdmType elemType = ConvertOSpaceToCSpaceType(((CollectionType)clrType).TypeUsage.EdmType); 
                cdmType = new CollectionType(elemType);
            } 
            else if (Helper.IsRowType(clrType)) 
            {
                List cdmProperties = new List(); 
                foreach (EdmProperty column in ((RowType)clrType).Properties)
                {
                    EdmType cdmPropertyType = ConvertOSpaceToCSpaceType(column.TypeUsage.EdmType);
                    EdmProperty cdmPorperty = new EdmProperty(column.Name, TypeUsage.Create(cdmPropertyType)); 
                    cdmProperties.Add(cdmPorperty);
                } 
                cdmType = new RowType(cdmProperties, ((RowType)clrType).InitializerMetadata); 
            }
            else if (Helper.IsRefType(clrType)) 
            {
                cdmType = new RefType((EntityType)(ConvertOSpaceToCSpaceType(((RefType)clrType).ElementType)));
            }
            else 
            {
                cdmType = ((ObjectTypeMapping)GetMap(clrType)).EdmType; 
            } 
            Debug.Assert((null != cdmType), "null converted clr type");
            return cdmType; 
        }

        /// 
        /// checks if the schemaKey refers to the primitive OC mapping schema and if true, 
        /// loads the maps between primitive types
        ///  
        /// returns the loaded schema if the schema key refers to a primitive schema 
        private void LoadPrimitiveMaps() {
            // Get all the primitive types from the CSpace and create OCMaps for it 
            IEnumerable cspaceTypes = m_edmCollection.GetPrimitiveTypes();
            foreach (PrimitiveType type in cspaceTypes)
            {
                PrimitiveType ospaceType = m_objectCollection.GetMappedPrimitiveType(type.PrimitiveTypeKind); 
                Debug.Assert(ospaceType != null, "all primitive type must have been loaded");
                this.AddInternalMapping(new ObjectTypeMapping(ospaceType, type)); 
            } 
        }
 
        // Add to the cache. If it is already present, then throw an exception
        private void AddInternalMapping(ObjectTypeMapping objectMap)
        {
            string clrName = objectMap.ClrType.Identity; 
            string cdmName = objectMap.EdmType.Identity;
            int currIndex = this.Count; 
            //Always assume that the first Map for an associated map being added is 
            //the default map for primitive type. Similarly, row and collection types can collide
            //because their components are primitive types. For other types, 
            //there should be only one map
            if (clrTypeIndexes.ContainsKey(clrName))
            {
                if (BuiltInTypeKind.PrimitiveType != objectMap.ClrType.BuiltInTypeKind && 
                    BuiltInTypeKind.RowType != objectMap.ClrType.BuiltInTypeKind &&
                    BuiltInTypeKind.CollectionType != objectMap.ClrType.BuiltInTypeKind) 
                { 
                    throw new MappingException(System.Data.Entity.Strings.Mapping_Duplicate_Type_1(clrName));
                } 
            }
            else
            {
                clrTypeIndexes.Add(clrName, currIndex); 
            }
            if (cdmTypeIndexes.ContainsKey(cdmName)) 
            { 
                if (BuiltInTypeKind.PrimitiveType != objectMap.EdmType.BuiltInTypeKind &&
                    BuiltInTypeKind.RowType != objectMap.EdmType.BuiltInTypeKind && 
                    BuiltInTypeKind.CollectionType != objectMap.EdmType.BuiltInTypeKind)
                {
                    throw new MappingException(System.Data.Entity.Strings.Mapping_Duplicate_Type_1(clrName));
                } 
            }
            else 
            { 
                cdmTypeIndexes.Add(cdmName, currIndex);
            } 
            objectMap.DataSpace = DataSpace.OCSpace;
            base.AddInternal (objectMap);
        }
 
        /// 
        /// The method fills up the children of ObjectMapping. It goes through the 
        /// members in CDM type and finds the member in Object space with the same name 
        /// and creates a member map between them. These member maps are added
        /// as children of the object mapping. 
        /// 
        /// 
        /// 
        ///  
        internal static ObjectTypeMapping LoadObjectMapping(EdmType cdmType, EdmType objectType, DefaultObjectMappingItemCollection ocItemCollection)
        { 
            Dictionary typeMappings = new Dictionary(StringComparer.Ordinal); 
            ObjectTypeMapping typeMapping = LoadObjectMapping(cdmType, objectType, ocItemCollection, typeMappings);
 
            // If DefaultOCMappingItemCollection is not null, add all the type mappings to the item collection
            if (ocItemCollection != null)
            {
                foreach (ObjectTypeMapping map in typeMappings.Values) 
                {
                    ocItemCollection.AddInternalMapping(map); 
                } 
            }
 
            return typeMapping;
        }

        private static ObjectTypeMapping LoadObjectMapping(EdmType edmType, EdmType objectType, DefaultObjectMappingItemCollection ocItemCollection, 
            Dictionary typeMappings)
        { 
            Debug.Assert((edmType != null) && (objectType != null)); 
            Debug.Assert((edmType.BuiltInTypeKind == objectType.BuiltInTypeKind), "The BuiltInTypeKind must be same in LoadObjectMapping");
 
            // Check if both the types are abstract or both of them are not
            if (edmType.Abstract != objectType.Abstract)
            {
                throw new MappingException(System.Data.Entity.Strings.Mapping_AbstractTypeMappingToNonAbstractType(edmType.FullName, objectType.FullName)); 
            }
 
            ObjectTypeMapping objectTypeMapping = new ObjectTypeMapping(objectType, edmType); 
            typeMappings.Add(edmType.FullName, objectTypeMapping);
 
            if (edmType.BuiltInTypeKind == BuiltInTypeKind.EntityType || edmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType)
            {
                LoadEntityTypeOrComplexTypeMapping(objectTypeMapping, edmType, objectType, ocItemCollection, typeMappings);
            } 
            else
            { 
                LoadAssociationTypeMapping(objectTypeMapping, edmType, objectType, ocItemCollection, typeMappings); 
            }
 
            return objectTypeMapping;
        }

        ///  
        /// Tries and get the mapping ospace member for the given edmMember and the ospace type
        ///  
        ///  
        /// 
        ///  
        /// Validates the scalar property on the cspace side and ospace side and creates a new
        /// ObjectPropertyMapping, if everything maps property
        /// 
        ///  
        /// 
        ///  
        private static ObjectPropertyMapping LoadScalarPropertyMapping(EdmProperty edmProperty, EdmProperty objectProperty) 
        {
            Debug.Assert(Helper.IsPrimitiveType(edmProperty.TypeUsage.EdmType), "Only edm scalar properties expected"); 
            Debug.Assert(Helper.IsPrimitiveType(objectProperty.TypeUsage.EdmType), "Only object scalar properties expected");

            return new ObjectPropertyMapping(edmProperty, objectProperty);
        } 

        ///  
        /// Load the entity type or complex type mapping 
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        private static void LoadEntityTypeOrComplexTypeMapping(ObjectTypeMapping objectMapping, EdmType edmType, EdmType objectType,
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary typeMappings) 
        { 
            Debug.Assert(edmType.BuiltInTypeKind == BuiltInTypeKind.EntityType ||
                    edmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, 
                    "Expected Type Encountered in LoadEntityTypeOrComplexTypeMapping");
            Debug.Assert((edmType.BuiltInTypeKind == objectType.BuiltInTypeKind), "The BuiltInTypeKind must be same in LoadEntityTypeOrComplexTypeMapping");

            StructuralType cdmStructuralType = (StructuralType)edmType; 
            StructuralType objectStructuralType = (StructuralType)objectType;
 
            if (cdmStructuralType.Members.Count != objectStructuralType.Members.Count) 
            {
                throw new MappingException(System.Data.Entity.Strings.Mapping_Default_OCMapping_Member_Count_Mismatch_2( 
                          edmType.FullName, objectType.FullName));
            }

            //Go through the CDMMembers and find the corresponding member in Object space 
            //and create a member map.
            foreach (EdmMember edmMember in cdmStructuralType.Members) 
            { 
                EdmMember objectMember = GetObjectMember(edmMember, objectStructuralType);
 
                if (Helper.IsEdmProperty(edmMember))
                {
                    EdmProperty edmPropertyMember = (EdmProperty)edmMember;
                    EdmProperty edmPropertyObject = (EdmProperty)objectMember; 

                    //Depending on the type of member load the member mapping i.e. For complex 
                    //members we have to go in and load the child members of the Complex type. 
                    if (Helper.IsComplexType(edmMember.TypeUsage.EdmType))
                    { 
                        objectMapping.AddMemberMap(
                            LoadComplexMemberMapping(edmPropertyMember, edmPropertyObject, ocItemCollection, typeMappings));
                    }
                    else 
                    {
                        objectMapping.AddMemberMap( 
                            LoadScalarPropertyMapping(edmPropertyMember, edmPropertyObject)); 
                    }
                } 
                else
                {
                    Debug.Assert(edmMember.BuiltInTypeKind == BuiltInTypeKind.NavigationProperty, "Unexpected Property type encountered");
 
                    // For navigation properties, we need to make sure the relationship type on the navigation property is mapped
                    NavigationProperty navigationProperty = (NavigationProperty)edmMember; 
                    NavigationProperty objectNavigationProperty = (NavigationProperty)objectMember; 
                    LoadTypeMapping(navigationProperty.RelationshipType, objectNavigationProperty.RelationshipType, ocItemCollection, typeMappings);
 
                    objectMapping.AddMemberMap(new ObjectNavigationPropertyMapping(navigationProperty, objectNavigationProperty));
                }
            }
        } 

        ///  
        /// Loads Association Type Mapping 
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        private static void LoadAssociationTypeMapping(ObjectTypeMapping objectMapping, EdmType edmType, EdmType objectType,
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary typeMappings) 
        { 
            Debug.Assert(edmType.BuiltInTypeKind == BuiltInTypeKind.AssociationType, "Expected Type Encountered in LoadAssociationTypeMapping");
            Debug.Assert((edmType.BuiltInTypeKind == objectType.BuiltInTypeKind), "The BuiltInTypeKind must be same in LoadAssociationTypeMapping"); 

            AssociationType association = (AssociationType)edmType;
            AssociationType objectAssociation = (AssociationType)objectType;
 
            foreach (AssociationEndMember edmEnd in association.AssociationEndMembers)
            { 
                AssociationEndMember objectEnd = (AssociationEndMember)GetObjectMember(edmEnd, objectAssociation); 

                if (edmEnd.RelationshipMultiplicity != objectEnd.RelationshipMultiplicity) 
                {
                    throw new MappingException(System.Data.Entity.Strings.Mapping_Default_OCMapping_MultiplicityMismatch_6(
                        edmEnd.RelationshipMultiplicity, edmEnd.Name, association.FullName,
                        objectEnd.RelationshipMultiplicity, objectEnd.Name, objectAssociation.FullName)); 
                }
 
                Debug.Assert(edmEnd.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.RefType, "Ends must be of Ref type"); 

                // GetMap for the entity types for the ends of the relationship type to make sure 
                // the entity type mentioned are valid
                LoadTypeMapping(((RefType)edmEnd.TypeUsage.EdmType).ElementType,
                                ((RefType)objectEnd.TypeUsage.EdmType).ElementType, ocItemCollection, typeMappings);
 
                objectMapping.AddMemberMap(new ObjectAssociationEndMapping(edmEnd, objectEnd));
            } 
        } 

        ///  
        /// The method loads the EdmMember mapping for complex members.
        /// It goes through the CDM members of the Complex Cdm type and
        /// tries to find the corresponding members in Complex Clr type.
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        private static ObjectComplexPropertyMapping LoadComplexMemberMapping(EdmProperty containingEdmMember, EdmProperty containingClrMember,
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary typeMappings)
        {
            Debug.Assert(containingEdmMember.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, "edm member declaringType must be of complexType"); 
            Debug.Assert(containingClrMember.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, "clr member declaringType must be of complexType");
 
            ComplexType edmComplexType = (ComplexType)containingEdmMember.TypeUsage.EdmType; 
            ComplexType objectComplexType = (ComplexType)containingClrMember.TypeUsage.EdmType;
 
            // Get the type mapping for the complex type
            ObjectTypeMapping complexTypeMapping = LoadTypeMapping(edmComplexType, objectComplexType, ocItemCollection, typeMappings);

            //Go through the CDMMembers and find the corresponding member in Object space 
            //and create a member map.
            return new ObjectComplexPropertyMapping(containingEdmMember, containingClrMember, complexTypeMapping); 
        } 

        private static ObjectTypeMapping LoadTypeMapping(EdmType edmType, EdmType objectType, 
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary typeMappings)
        {
            ObjectTypeMapping objectTypeMapping;
 
            //First, check in the type mappings to find out if the mapping is already present
            if (typeMappings.TryGetValue(edmType.FullName, out objectTypeMapping)) 
            { 
                return objectTypeMapping;
            } 

            if (ocItemCollection != null)
            {
                ObjectTypeMapping typeMapping; 

                if (ocItemCollection.ContainsMap(edmType, out typeMapping)) 
                { 
                    return (ObjectTypeMapping)typeMapping;
                } 
            }

            // If the type mapping is not already loaded, then load it
            return LoadObjectMapping(edmType, objectType, ocItemCollection, typeMappings); 
        }
 
        private bool ContainsMap(GlobalItem cspaceItem, out ObjectTypeMapping map) 
        {
            Debug.Assert(cspaceItem.DataSpace == DataSpace.CSpace, "ContainsMap: It must be a CSpace item"); 
            int index;
            if (cdmTypeIndexes.TryGetValue(cspaceItem.Identity, out index))
            {
                map = (ObjectTypeMapping)this[index]; 
                return true;
            } 
 
            map = null;
            return false; 
        }

        #endregion
    } 
}

// 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