/// <summary>
        /// Loads Association Type Mapping
        /// </summary>
        /// <param name="objectMapping"></param>
        /// <param name="edmType"></param>
        /// <param name="objectType"></param>
        /// <param name="ocItemCollection"></param>
        /// <param name="typeMappings"></param>
        private static void LoadAssociationTypeMapping(ObjectTypeMapping objectMapping, EdmType edmType, EdmType objectType,
                                                       DefaultObjectMappingItemCollection ocItemCollection, Dictionary <string, ObjectTypeMapping> 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);
                ValidateMembersMatch(edmEnd, objectEnd);

                if (edmEnd.RelationshipMultiplicity != objectEnd.RelationshipMultiplicity)
                {
                    throw new MappingException(System.Data.Entity.Strings.Mapping_Default_OCMapping_MultiplicityMismatch(
                                                   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));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Retrieves a mapping to CLR type for the given EDM type. Assumes the MetadataWorkspace has no    
        /// </summary>
        internal static ObjectTypeMapping GetObjectMapping(EdmType type, MetadataWorkspace workspace)
        {
            // Check if the workspace has cspace item collection registered with it. If not, then its a case
            // of public materializer trying to create objects from PODR or EntityDataReader with no context.
            ItemCollection collection;
            if (workspace.TryGetItemCollection(DataSpace.CSpace, out collection))
            {
                return (ObjectTypeMapping)workspace.GetMap(type, DataSpace.OCSpace);
            }
            else
            {
                EdmType ospaceType;
                EdmType cspaceType;
                // If its a case of EntityDataReader with no context, the typeUsage which is passed in must contain
                // a cspace type. We need to look up an OSpace type in the ospace item collection and then create
                // ocMapping
                if (type.DataSpace == DataSpace.CSpace)
                {
                    // if its a primitive type, then the names will be different for CSpace type and OSpace type
                    if (Helper.IsPrimitiveType(type))
                    {
                        ospaceType = workspace.GetMappedPrimitiveType(((PrimitiveType)type).PrimitiveTypeKind, DataSpace.OSpace);
                    }
                    else
                    {
                        // Metadata will throw if there is no item with this identity present.
                        // Is this exception fine or does object materializer code wants to wrap and throw a new exception
                        ospaceType = workspace.GetItem<EdmType>(type.FullName, DataSpace.OSpace);
                    }
                    cspaceType = type;
                }
                else
                {
                    // In case of PODR, there is no cspace at all. We must create a fake ocmapping, with ospace types
                    // on both the ends
                    ospaceType = type;
                    cspaceType = type;
                }

                // This condition must be hit only when someone is trying to materialize a legacy data reader and we
                // don't have the CSpace metadata.
                if (!Helper.IsPrimitiveType(ospaceType) && !Helper.IsEntityType(ospaceType) && !Helper.IsComplexType(ospaceType))
                {
                    throw EntityUtil.MaterializerUnsupportedType();
                }

                ObjectTypeMapping typeMapping;

                if (Helper.IsPrimitiveType(ospaceType))
                {
                    typeMapping = new ObjectTypeMapping(ospaceType, cspaceType);
                }
                else
                {
                    typeMapping = DefaultObjectMappingItemCollection.LoadObjectMapping(cspaceType, ospaceType, null);
                }

                return typeMapping;
            }
        }
        /// <summary>
        /// Load the entity type or complex type mapping
        /// </summary>
        /// <param name="objectMapping"></param>
        /// <param name="edmType"></param>
        /// <param name="objectType"></param>
        /// <param name="ocItemCollection">
        /// <param name="typeMappings"></param></param>
        private static void LoadEntityTypeOrComplexTypeMapping(ObjectTypeMapping objectMapping, EdmType edmType, EdmType objectType,
                                                               DefaultObjectMappingItemCollection ocItemCollection, Dictionary <string, ObjectTypeMapping> 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;

            ValidateAllMembersAreMapped(cdmStructuralType, objectStructuralType);

            //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);
                ValidateMembersMatch(edmMember, objectMember);

                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));
                }
            }
        }
        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);
        }
        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);
        }
        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="cdmType"></param>
        /// <param name="objectType"></param>
        /// <param name="ocItemCollection"></param>
        internal static ObjectTypeMapping LoadObjectMapping(EdmType cdmType, EdmType objectType, DefaultObjectMappingItemCollection ocItemCollection)
        {
            Dictionary <string, ObjectTypeMapping> typeMappings = new Dictionary <string, ObjectTypeMapping>(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);
        }
        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="containingEdmMember"></param>
        /// <param name="containingClrMember"></param>
        /// <param name="ocItemCollection"></param>
        /// <param name="typeMappings"></param>
        /// <returns></returns>
        private static ObjectComplexPropertyMapping LoadComplexMemberMapping(EdmProperty containingEdmMember, EdmProperty containingClrMember,
                                                                             DefaultObjectMappingItemCollection ocItemCollection, Dictionary <string, ObjectTypeMapping> 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));
        }
        internal StateManagerTypeMetadata(EdmType edmType, ObjectTypeMapping mapping)
        {
            Debug.Assert(null != edmType, "null EdmType");
            Debug.Assert(
                Helper.IsEntityType(edmType) ||
                Helper.IsComplexType(edmType),
                "not Complex or EntityType");
            Debug.Assert(
                ReferenceEquals(mapping, null) ||
                ReferenceEquals(mapping.EdmType, edmType),
                "different EdmType instance");

            _typeUsage = TypeUsage.Create(edmType);
            _recordInfo = new DataRecordInfo(_typeUsage);

            var members = TypeHelpers.GetProperties(edmType);
            _members = new StateManagerMemberMetadata[members.Count];
            _objectNameToOrdinal = new Dictionary<string, int>(members.Count);
            _cLayerNameToOrdinal = new Dictionary<string, int>(members.Count);

            ReadOnlyMetadataCollection<EdmMember> keyMembers = null;
            if (Helper.IsEntityType(edmType))
            {
                keyMembers = ((EntityType)edmType).KeyMembers;
            }

            for (var i = 0; i < _members.Length; ++i)
            {
                var member = members[i];

                ObjectPropertyMapping memberMap = null;
                if (null != mapping)
                {
                    memberMap = mapping.GetPropertyMap(member.Name);
                    if (null != memberMap)
                    {
                        _objectNameToOrdinal.Add(memberMap.ClrProperty.Name, i); // olayer name
                    }
                }
                _cLayerNameToOrdinal.Add(member.Name, i); // clayer name

                // Determine whether this member is part of the identity of the entity.
                _members[i] = new StateManagerMemberMetadata(memberMap, member, ((null != keyMembers) && keyMembers.Contains(member)));
            }
        }
        // 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(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(clrName));
                }
            }
            else
            {
                cdmTypeIndexes.Add(cdmName, currIndex);
            }
            objectMap.DataSpace = DataSpace.OCSpace;
            base.AddInternal(objectMap);
        }
        private static ObjectTypeMapping LoadObjectMapping(EdmType edmType, EdmType objectType, DefaultObjectMappingItemCollection ocItemCollection,
                                                           Dictionary <string, ObjectTypeMapping> typeMappings)
        {
            Debug.Assert((edmType != null) && (objectType != null));
            Debug.Assert((edmType.BuiltInTypeKind == objectType.BuiltInTypeKind), "The BuiltInTypeKind must be same in LoadObjectMapping");

            if (Helper.IsEnumType(edmType) ^ Helper.IsEnumType(objectType))
            {
                throw new MappingException(System.Data.Entity.Strings.Mapping_EnumTypeMappingToNonEnumType(edmType.FullName, objectType.FullName));
            }

            // 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 (Helper.IsEntityType(edmType) || Helper.IsComplexType(edmType))
            {
                LoadEntityTypeOrComplexTypeMapping(objectTypeMapping, edmType, objectType, ocItemCollection, typeMappings);
            }
            else if (Helper.IsEnumType(edmType))
            {
                ValidateEnumTypeMapping((EnumType)edmType, (EnumType)objectType);
            }
            else
            {
                Debug.Assert(Helper.IsAssociationType(edmType));

                LoadAssociationTypeMapping(objectTypeMapping, edmType, objectType, ocItemCollection, typeMappings);
            }

            return(objectTypeMapping);
        }
 /// <summary>
 /// Constrcut a new member mapping metadata object
 /// </summary>
 /// <param name="edmProperty"></param>
 /// <param name="clrProperty"></param>
 /// <param name="complexTypeMapping"></param>
 internal ObjectComplexPropertyMapping(EdmProperty edmProperty, EdmProperty clrProperty, ObjectTypeMapping complexTypeMapping)
     : base(edmProperty, clrProperty)
 {
     m_objectTypeMapping = complexTypeMapping;
 }
 /// <summary>
 /// Constrcut a new member mapping metadata object
 /// </summary>
 /// <param name="edmProperty"></param>
 /// <param name="clrProperty"></param>
 /// <param name="complexTypeMapping"></param>
 internal ObjectComplexPropertyMapping(EdmProperty edmProperty, EdmProperty clrProperty, ObjectTypeMapping complexTypeMapping)
     : base(edmProperty, clrProperty)
 {
     m_objectTypeMapping = complexTypeMapping;
 }
        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;
        }
 // 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(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(clrName));
         }
     }
     else
     {
         cdmTypeIndexes.Add(cdmName, currIndex);
     }
     objectMap.DataSpace = DataSpace.OCSpace;
     base.AddInternal (objectMap);
 }
        private static ObjectTypeMapping LoadObjectMapping(EdmType edmType, EdmType objectType, DefaultObjectMappingItemCollection ocItemCollection,
            Dictionary<string, ObjectTypeMapping> typeMappings)
        {
            Debug.Assert((edmType != null) && (objectType != null));
            Debug.Assert((edmType.BuiltInTypeKind == objectType.BuiltInTypeKind), "The BuiltInTypeKind must be same in LoadObjectMapping");

            if (Helper.IsEnumType(edmType) ^ Helper.IsEnumType(objectType))
            {
                throw new MappingException(System.Data.Entity.Strings.Mapping_EnumTypeMappingToNonEnumType(edmType.FullName, objectType.FullName));
            }

            // 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 (Helper.IsEntityType(edmType) || Helper.IsComplexType(edmType))
            {
                LoadEntityTypeOrComplexTypeMapping(objectTypeMapping, edmType, objectType, ocItemCollection, typeMappings);
            }
            else if (Helper.IsEnumType(edmType))
            {
                ValidateEnumTypeMapping((EnumType)edmType, (EnumType)objectType);
            }
            else
            {
                Debug.Assert(Helper.IsAssociationType(edmType));

                LoadAssociationTypeMapping(objectTypeMapping, edmType, objectType, ocItemCollection, typeMappings);
            }

            return objectTypeMapping;
        }
        /// <summary>
        /// Load the entity type or complex type mapping
        /// </summary>
        /// <param name="objectMapping"></param>
        /// <param name="edmType"></param>
        /// <param name="objectType"></param>
        /// <param name="ocItemCollection">
        /// <param name="typeMappings"></param></param>
        private static void LoadEntityTypeOrComplexTypeMapping(ObjectTypeMapping objectMapping, EdmType edmType, EdmType objectType,
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary<string, ObjectTypeMapping> 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;

            ValidateAllMembersAreMapped(cdmStructuralType, objectStructuralType);

            //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);
                ValidateMembersMatch(edmMember, objectMember);

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

            }
        }
        /// <summary>
        /// Loads Association Type Mapping
        /// </summary>
        /// <param name="objectMapping"></param>
        /// <param name="edmType"></param>
        /// <param name="objectType"></param>
        /// <param name="ocItemCollection"></param>
        /// <param name="typeMappings"></param>
        private static void LoadAssociationTypeMapping(ObjectTypeMapping objectMapping, EdmType edmType, EdmType objectType,
            DefaultObjectMappingItemCollection ocItemCollection, Dictionary<string, ObjectTypeMapping> 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);
                ValidateMembersMatch(edmEnd, objectEnd);

                if (edmEnd.RelationshipMultiplicity != objectEnd.RelationshipMultiplicity)
                {
                    throw new MappingException(System.Data.Entity.Strings.Mapping_Default_OCMapping_MultiplicityMismatch(
                        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));
            }
        }
        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;
        }
            internal Plan(TypeUsage key, ObjectTypeMapping mapping, System.Collections.ObjectModel.ReadOnlyCollection<FieldMetadata> fields)
            {
                Debug.Assert(null != mapping, "null ObjectTypeMapping");
                Debug.Assert(null != fields, "null FieldMetadata");

                Key = key;
                Debug.Assert(!Helper.IsEntityType(mapping.ClrType), "Expecting complex type");
                ClrType = LightweightCodeGenerator.GetConstructorDelegateForType((ClrComplexType)mapping.ClrType);
                Properties = new PlanEdmProperty[fields.Count];

                int lastOrdinal = -1;
                for (int i = 0; i < Properties.Length; ++i)
                {
                    FieldMetadata field = fields[i];

                    Debug.Assert(unchecked((uint)field.Ordinal) < unchecked((uint)fields.Count), "FieldMetadata.Ordinal out of range of Fields.Count");
                    Debug.Assert(lastOrdinal < field.Ordinal, "FieldMetadata.Ordinal is not increasing");
                    lastOrdinal = field.Ordinal;

                    Properties[i] = new PlanEdmProperty(lastOrdinal, mapping.GetPropertyMap(field.FieldType.Name).ClrProperty);
                }
            }