1 //---------------------------------------------------------------------
2 // <copyright file="ClrPerspective.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
10 namespace System.Data.Metadata.Edm
12 using System.Collections.Generic;
13 using System.Data.Mapping;
14 using System.Diagnostics;
17 /// Internal helper class for query
19 internal sealed class ClrPerspective : Perspective
21 private EntityContainer _defaultContainer;
25 /// Creates a new instance of perspective class so that query can work
26 /// ignorant of all spaces
28 /// <param name="metadataWorkspace"></param>
29 internal ClrPerspective(MetadataWorkspace metadataWorkspace)
30 : base(metadataWorkspace, DataSpace.CSpace)
33 #endregion //Constructors
37 /// Given a clrType attempt to return the corresponding target type from
40 /// <param name="clrType">The clr type to resolve</param>
41 /// <param name="outTypeUsage">an out param for the typeUsage to be resolved to</param>
42 /// <returns>true if a TypeUsage can be found for the target type</returns>
43 internal bool TryGetType(Type clrType, out TypeUsage outTypeUsage)
45 return TryGetTypeByName(clrType.FullName,
51 /// Given the type in the target space and the member name in the source space,
52 /// get the corresponding member in the target space
53 /// For e.g. consider a Conceptual Type Foo with a member bar and a CLR type
54 /// XFoo with a member YBar. If one has a reference to Foo one can
55 /// invoke GetMember(Foo,"YBar") to retrieve the member metadata for bar
57 /// <param name="type">The type in the target perspective</param>
58 /// <param name="memberName">the name of the member in the source perspective</param>
59 /// <param name="ignoreCase">true for case-insensitive lookup</param>
60 /// <param name="outMember">returns the edmMember if a match is found</param>
61 /// <returns>true if a match is found, otherwise false</returns>
62 internal override bool TryGetMember(StructuralType type, String memberName, bool ignoreCase, out EdmMember outMember)
67 if (this.MetadataWorkspace.TryGetMap(type, DataSpace.OCSpace, out map))
69 ObjectTypeMapping objectTypeMap = map as ObjectTypeMapping;
71 if (objectTypeMap!=null)
73 ObjectMemberMapping objPropertyMapping = objectTypeMap.GetMemberMapForClrMember(memberName, ignoreCase);
74 if (null != objPropertyMapping)
76 outMember = objPropertyMapping.EdmMember;
85 /// Look up a type in the target data space based upon the fullName
87 /// <param name="fullName">fullName</param>
88 /// <param name="ignoreCase">true for case-insensitive lookup</param>
89 /// <param name="typeUsage">The type usage object to return</param>
90 /// <returns>True if the retrieval succeeded</returns>
91 internal override bool TryGetTypeByName(string fullName, bool ignoreCase, out TypeUsage typeUsage)
96 // From ClrPerspective, we should not allow anything from SSpace. So make sure that the CSpace type does not
97 // have the Target attribute
98 if (this.MetadataWorkspace.TryGetMap(fullName, DataSpace.OSpace, ignoreCase, DataSpace.OCSpace, out map))
100 // Check if it's primitive type, if so, then use the MetadataWorkspace to get the mapped primitive type
101 if (map.EdmItem.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
103 // Reassign the variable with the provider primitive type, then create the type usage
104 PrimitiveType primitiveType = this.MetadataWorkspace.GetMappedPrimitiveType(((PrimitiveType)map.EdmItem).PrimitiveTypeKind, DataSpace.CSpace);
105 if (primitiveType != null)
107 typeUsage = EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(primitiveType.PrimitiveTypeKind);
112 Debug.Assert(((GlobalItem)map.EdmItem).DataSpace == DataSpace.CSpace);
113 typeUsage = GetMappedTypeUsage(map);
117 return (null != typeUsage);
121 /// get the default container
123 /// <returns>The default container</returns>
124 internal override EntityContainer GetDefaultContainer()
126 return _defaultContainer;
129 internal void SetDefaultContainer(string defaultContainerName)
131 EntityContainer container = null;
132 if (!String.IsNullOrEmpty(defaultContainerName))
134 if (!MetadataWorkspace.TryGetEntityContainer(defaultContainerName, DataSpace.CSpace, out container))
136 throw EntityUtil.InvalidDefaultContainerName("defaultContainerName", defaultContainerName);
139 _defaultContainer = container;
143 /// Given a map, dereference the EdmItem, ensure that it is
144 /// an EdmType and return a TypeUsage for the type, otherwise
147 /// <param name="map">The OC map to use to get the EdmType</param>
148 /// <returns>A TypeUsage for the mapped EdmType or null if no EdmType was mapped</returns>
149 private static TypeUsage GetMappedTypeUsage(Map map)
151 TypeUsage typeUsage = null;
154 MetadataItem item = map.EdmItem;
155 EdmType edmItem = item as EdmType;
156 if (null != item && edmItem!=null)
158 typeUsage = TypeUsage.Create(edmItem);