// <summary> // A helper method returning the underlying CLR type for the specified OSpace enum or structural type argument. // If the DataSpace of the parameter is not OSpace, the method returns false and sets // the out parameter to null. // </summary> // <param name="objectSpaceType"> The OSpace enum type to look up </param> // <param name="clrType"> The CLR enum type of the OSpace argument </param> // <returns> true on success, false on failure </returns> private static bool TryGetClrType(EdmType objectSpaceType, out Type clrType) { DebugCheck.NotNull(objectSpaceType); Debug.Assert( objectSpaceType == null || objectSpaceType is StructuralType || objectSpaceType is EnumType, "Only enum or structural type expected"); if (objectSpaceType.DataSpace != DataSpace.OSpace) { throw new ArgumentException(Strings.ArgumentMustBeOSpaceType, "objectSpaceType"); } clrType = null; if (Helper.IsEntityType(objectSpaceType) || Helper.IsComplexType(objectSpaceType) || Helper.IsEnumType(objectSpaceType)) { Debug.Assert( objectSpaceType is ClrEntityType || objectSpaceType is ClrComplexType || objectSpaceType is ClrEnumType, "Unexpected OSpace object type."); clrType = objectSpaceType.ClrType; Debug.Assert(clrType != null, "ClrType property of ClrEntityType/ClrComplexType/ClrEnumType objects must not be null"); } return(clrType != null); }
internal virtual void AddLoadedTypes(Dictionary <string, EdmType> typesInLoading) { List <GlobalItem> items = new List <GlobalItem>(); foreach (EdmType edmType in typesInLoading.Values) { items.Add((GlobalItem)edmType); string key = ""; try { if (Helper.IsEntityType(edmType)) { key = ((ClrEntityType)edmType).CSpaceTypeName; this._ocMapping.Add(key, edmType); } else if (Helper.IsComplexType(edmType)) { key = ((ClrComplexType)edmType).CSpaceTypeName; this._ocMapping.Add(key, edmType); } else if (Helper.IsEnumType(edmType)) { key = ((ClrEnumType)edmType).CSpaceTypeName; this._ocMapping.Add(key, edmType); } } catch (ArgumentException ex) { throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes((object)key), (Exception)ex); } } this.AddRange(items); }
private bool TryCreateStructuralType( Type type, StructuralType cspaceType, out EdmType newOSpaceType) { List <Action> referenceResolutionListForCurrentType = new List <Action>(); newOSpaceType = (EdmType)null; StructuralType ospaceType = !Helper.IsEntityType((EdmType)cspaceType) ? (StructuralType) new ClrComplexType(type, cspaceType.NamespaceName, cspaceType.Name) : (StructuralType) new ClrEntityType(type, cspaceType.NamespaceName, cspaceType.Name); if (cspaceType.BaseType != null) { if (OSpaceTypeFactory.TypesMatchByConvention(type.BaseType(), cspaceType.BaseType)) { this.TrackClosure(type.BaseType()); referenceResolutionListForCurrentType.Add((Action)(() => ospaceType.BaseType = this.ResolveBaseType((StructuralType)cspaceType.BaseType, type))); } else { this.LogLoadMessage(Strings.Validator_OSpace_Convention_BaseTypeIncompatible((object)type.BaseType().FullName, (object)type.FullName, (object)cspaceType.BaseType.FullName), (EdmType)cspaceType); return(false); } } if (!this.TryCreateMembers(type, cspaceType, ospaceType, referenceResolutionListForCurrentType)) { return(false); } this.LoadedTypes.Add(type.FullName, (EdmType)ospaceType); foreach (Action action in referenceResolutionListForCurrentType) { this.ReferenceResolutions.Add(action); } newOSpaceType = (EdmType)ospaceType; return(true); }
internal static ObjectTypeMapping GetObjectMapping( EdmType type, MetadataWorkspace workspace) { ItemCollection collection; if (workspace.TryGetItemCollection(DataSpace.CSpace, out collection)) { return((ObjectTypeMapping)workspace.GetMap((GlobalItem)type, DataSpace.OCSpace)); } EdmType edmType; EdmType cdmType; if (type.DataSpace == DataSpace.CSpace) { edmType = !Helper.IsPrimitiveType(type) ? workspace.GetItem <EdmType>(type.FullName, DataSpace.OSpace) : (EdmType)workspace.GetMappedPrimitiveType(((PrimitiveType)type).PrimitiveTypeKind, DataSpace.OSpace); cdmType = type; } else { edmType = type; cdmType = type; } if (!Helper.IsPrimitiveType(edmType) && !Helper.IsEntityType(edmType) && !Helper.IsComplexType(edmType)) { throw new NotSupportedException(Strings.Materializer_UnsupportedType); } return(!Helper.IsPrimitiveType(edmType) ? DefaultObjectMappingItemCollection.LoadObjectMapping(cdmType, edmType, (DefaultObjectMappingItemCollection)null) : new ObjectTypeMapping(edmType, cdmType)); }
internal static bool IsEntityTypeBase(EdmType edmType) { if (!Helper.IsEntityType(edmType)) { return(Helper.IsRelationshipType(edmType)); } return(true); }
internal static bool IsStructuralType(EdmType type) { if (!Helper.IsComplexType(type) && !Helper.IsEntityType(type) && !Helper.IsRelationshipType(type)) { return(Helper.IsRowType((GlobalItem)type)); } return(true); }
internal bool TryGetOSpaceType(EdmType cspaceType, out EdmType edmType) { if (Helper.IsEntityType(cspaceType) || Helper.IsComplexType(cspaceType) || Helper.IsEnumType(cspaceType)) { return(this._ocMapping.TryGetValue(cspaceType.Identity, out edmType)); } return(this.TryGetItem <EdmType>(cspaceType.Identity, out edmType)); }
/// <summary> /// Creates a structural OSpace type based on CLR type and CSpace type. /// </summary> /// <param name="type"> CLR type. </param> /// <param name="cspaceType"> CSpace Type </param> /// <param name="newOSpaceType"> /// OSpace type created based on CLR <paramref name="type" /> and <paramref name="cspaceType" /> /// </param> /// <returns> /// <c>true</c> if the type was created successfully. Otherwise <c>false</c> . /// </returns> private bool TryCreateStructuralType(Type type, StructuralType cspaceType, out EdmType newOSpaceType) { DebugCheck.NotNull(type); DebugCheck.NotNull(cspaceType); var referenceResolutionListForCurrentType = new List <Action>(); newOSpaceType = null; Debug.Assert(TypesMatchByConvention(type, cspaceType), "The types passed as parameters don't match by convention."); StructuralType ospaceType; if (Helper.IsEntityType(cspaceType)) { ospaceType = new ClrEntityType(type, cspaceType.NamespaceName, cspaceType.Name); } else { Debug.Assert(Helper.IsComplexType(cspaceType), "Invalid type attribute encountered"); ospaceType = new ClrComplexType(type, cspaceType.NamespaceName, cspaceType.Name); } if (cspaceType.BaseType != null) { if (TypesMatchByConvention(type.BaseType, cspaceType.BaseType)) { TrackClosure(type.BaseType); referenceResolutionListForCurrentType.Add( () => ospaceType.BaseType = ResolveBaseType((StructuralType)cspaceType.BaseType, type)); } else { var message = Strings.Validator_OSpace_Convention_BaseTypeIncompatible( type.BaseType.FullName, type.FullName, cspaceType.BaseType.FullName); SessionData.LoadMessageLogger.LogLoadMessage(message, cspaceType); return(false); } } // Load the properties for this type if (!TryCreateMembers(type, cspaceType, ospaceType, referenceResolutionListForCurrentType)) { return(false); } // Add this to the known type map so we won't try to load it again SessionData.TypesInLoading.Add(type.FullName, ospaceType); // we only add the referenceResolution to the list unless we structrually matched this type foreach (var referenceResolution in referenceResolutionListForCurrentType) { _referenceResolutions.Add(referenceResolution); } newOSpaceType = ospaceType; return(true); }
private void LoadType(Type clrType) { EdmType edmType = (EdmType)null; IEnumerable <EdmTypeAttribute> customAttributes = clrType.GetCustomAttributes <EdmTypeAttribute>(false); if (!customAttributes.Any <EdmTypeAttribute>()) { return; } if (clrType.IsNested) { this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.NestedClassNotSupported((object)clrType.FullName, (object)clrType.Assembly().FullName))); } else { EdmTypeAttribute edmTypeAttribute = customAttributes.First <EdmTypeAttribute>(); string cspaceTypeName = string.IsNullOrEmpty(edmTypeAttribute.Name) ? clrType.Name : edmTypeAttribute.Name; if (string.IsNullOrEmpty(edmTypeAttribute.NamespaceName) && clrType.Namespace == null) { this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_TypeHasNoNamespace)); } else { string cspaceNamespaceName = string.IsNullOrEmpty(edmTypeAttribute.NamespaceName) ? clrType.Namespace : edmTypeAttribute.NamespaceName; if (edmTypeAttribute.GetType() == typeof(EdmEntityTypeAttribute)) { edmType = (EdmType) new ClrEntityType(clrType, cspaceNamespaceName, cspaceTypeName); } else if (edmTypeAttribute.GetType() == typeof(EdmComplexTypeAttribute)) { edmType = (EdmType) new ClrComplexType(clrType, cspaceNamespaceName, cspaceTypeName); } else { PrimitiveType primitiveType; if (!ClrProviderManifest.Instance.TryGetPrimitiveType(clrType.GetEnumUnderlyingType(), out primitiveType)) { this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_UnsupportedEnumUnderlyingType((object)clrType.GetEnumUnderlyingType().FullName))); return; } edmType = (EdmType) new ClrEnumType(clrType, cspaceNamespaceName, cspaceTypeName); } this.CacheEntry.TypesInAssembly.Add(edmType); this.SessionData.TypesInLoading.Add(clrType.FullName, edmType); if (!Helper.IsStructuralType(edmType)) { return; } if (Helper.IsEntityType(edmType)) { this.TrackClosure(clrType.BaseType()); this.AddTypeResolver((Action)(() => edmType.BaseType = this.ResolveBaseType(clrType.BaseType()))); } this.LoadPropertiesFromType((StructuralType)edmType); } } }
private static bool TryGetClrType(EdmType objectSpaceType, out Type clrType) { if (objectSpaceType.DataSpace != DataSpace.OSpace) { throw new ArgumentException(Strings.ArgumentMustBeOSpaceType, nameof(objectSpaceType)); } clrType = (Type)null; if (Helper.IsEntityType(objectSpaceType) || Helper.IsComplexType(objectSpaceType) || Helper.IsEnumType(objectSpaceType)) { clrType = objectSpaceType.ClrType; } return(clrType != (Type)null); }
internal ObjectItemLoadingSessionData( KnownAssembliesSet knownAssemblies, LockedAssemblyCache lockedAssemblyCache, EdmItemCollection edmItemCollection, Action <String> logLoadMessage, object loaderCookie) { Debug.Assert( loaderCookie == null || loaderCookie is Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>, "This is a bad loader cookie"); _typesInLoading = new Dictionary <string, EdmType>(StringComparer.Ordinal); _errors = new List <EdmItemError>(); _knownAssemblies = knownAssemblies; _lockedAssemblyCache = lockedAssemblyCache; _loadersThatNeedLevel1PostSessionProcessing = new HashSet <ObjectItemAssemblyLoader>(); _loadersThatNeedLevel2PostSessionProcessing = new HashSet <ObjectItemAssemblyLoader>(); _edmItemCollection = edmItemCollection; _loadMessageLogger = new LoadMessageLogger(logLoadMessage); _cspaceToOspace = new Dictionary <EdmType, EdmType>(); _loaderFactory = (Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>)loaderCookie; _originalLoaderCookie = loaderCookie; if (_loaderFactory == ObjectItemConventionAssemblyLoader.Create && _edmItemCollection != null) { foreach (var entry in _knownAssemblies.GetEntries(_loaderFactory, edmItemCollection)) { foreach (var type in entry.CacheEntry.TypesInAssembly.OfType <EdmType>()) { if (Helper.IsEntityType(type)) { var entityType = (ClrEntityType)type; _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(entityType.CSpaceTypeName), entityType); } else if (Helper.IsComplexType(type)) { var complexType = (ClrComplexType)type; _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(complexType.CSpaceTypeName), complexType); } else if (Helper.IsEnumType(type)) { var enumType = (ClrEnumType)type; _cspaceToOspace.Add(_edmItemCollection.GetItem <EnumType>(enumType.CSpaceTypeName), enumType); } else { Debug.Assert(Helper.IsAssociationType(type)); _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(type.FullName), type); } } } } }
// <summary> // Get the OSpace type given the CSpace typename // </summary> internal bool TryGetOSpaceType(EdmType cspaceType, out EdmType edmType) { Debug.Assert(DataSpace.CSpace == cspaceType.DataSpace, "DataSpace should be CSpace"); // check if there is an entity, complex type or enum type mapping with this name if (Helper.IsEntityType(cspaceType) || Helper.IsComplexType(cspaceType) || Helper.IsEnumType(cspaceType)) { return(_ocMapping.TryGetValue(cspaceType.Identity, out edmType)); } return(TryGetItem(cspaceType.Identity, out edmType)); }
internal static string TryGetMappingCSpaceTypeIdentity(EdmType edmType) { if (Helper.IsEntityType(edmType)) { return(((ClrEntityType)edmType).CSpaceTypeName); } if (Helper.IsComplexType(edmType)) { return(((ClrComplexType)edmType).CSpaceTypeName); } if (Helper.IsEnumType(edmType)) { return(((ClrEnumType)edmType).CSpaceTypeName); } return(edmType.Identity); }
internal ObjectItemLoadingSessionData( KnownAssembliesSet knownAssemblies, LockedAssemblyCache lockedAssemblyCache, EdmItemCollection edmItemCollection, Action <string> logLoadMessage, object loaderCookie) { this._typesInLoading = new Dictionary <string, EdmType>((IEqualityComparer <string>)StringComparer.Ordinal); this._errors = new List <EdmItemError>(); this._knownAssemblies = knownAssemblies; this._lockedAssemblyCache = lockedAssemblyCache; this._edmItemCollection = edmItemCollection; this._loadMessageLogger = new LoadMessageLogger(logLoadMessage); this._cspaceToOspace = new Dictionary <EdmType, EdmType>(); this._loaderFactory = (Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>)loaderCookie; this._originalLoaderCookie = loaderCookie; if (!(this._loaderFactory == new Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>(ObjectItemConventionAssemblyLoader.Create)) || this._edmItemCollection == null) { return; } foreach (KnownAssemblyEntry entry in this._knownAssemblies.GetEntries((object)this._loaderFactory, edmItemCollection)) { foreach (EdmType edmType in entry.CacheEntry.TypesInAssembly.OfType <EdmType>()) { if (Helper.IsEntityType(edmType)) { ClrEntityType clrEntityType = (ClrEntityType)edmType; this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <StructuralType>(clrEntityType.CSpaceTypeName), (EdmType)clrEntityType); } else if (Helper.IsComplexType(edmType)) { ClrComplexType clrComplexType = (ClrComplexType)edmType; this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <StructuralType>(clrComplexType.CSpaceTypeName), (EdmType)clrComplexType); } else if (Helper.IsEnumType(edmType)) { ClrEnumType clrEnumType = (ClrEnumType)edmType; this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <EnumType>(clrEnumType.CSpaceTypeName), (EdmType)clrEnumType); } else { this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <StructuralType>(edmType.FullName), edmType); } } } }
private bool TryGetRelationshipEndEntityType(Type type, out EntityType entityType) { if (type == (Type)null) { entityType = (EntityType)null; return(false); } EdmType edmType; if (!this.TryGetLoadedType(type, out edmType) || !Helper.IsEntityType(edmType)) { entityType = (EntityType)null; return(false); } entityType = (EntityType)edmType; return(true); }
private void LoadPropertiesFromType(StructuralType structuralType) { foreach (PropertyInfo propertyInfo in structuralType.ClrType.GetDeclaredProperties().Where <PropertyInfo>((Func <PropertyInfo, bool>)(p => !p.IsStatic()))) { EdmMember member = (EdmMember)null; bool isEntityKeyProperty = false; if (propertyInfo.GetCustomAttributes <EdmRelationshipNavigationPropertyAttribute>(false).Any <EdmRelationshipNavigationPropertyAttribute>()) { PropertyInfo pi = propertyInfo; this._unresolvedNavigationProperties.Add((Action)(() => this.ResolveNavigationProperty(structuralType, pi))); } else if (propertyInfo.GetCustomAttributes <EdmScalarPropertyAttribute>(false).Any <EdmScalarPropertyAttribute>()) { Type type = Nullable.GetUnderlyingType(propertyInfo.PropertyType); if ((object)type == null) { type = propertyInfo.PropertyType; } if (type.IsEnum()) { this.TrackClosure(propertyInfo.PropertyType); PropertyInfo local = propertyInfo; this.AddTypeResolver((Action)(() => this.ResolveEnumTypeProperty(structuralType, local))); } else { member = this.LoadScalarProperty(structuralType.ClrType, propertyInfo, out isEntityKeyProperty); } } else if (propertyInfo.GetCustomAttributes <EdmComplexPropertyAttribute>(false).Any <EdmComplexPropertyAttribute>()) { this.TrackClosure(propertyInfo.PropertyType); PropertyInfo local = propertyInfo; this.AddTypeResolver((Action)(() => this.ResolveComplexTypeProperty(structuralType, local))); } if (member != null) { structuralType.AddMember(member); if (Helper.IsEntityType((EdmType)structuralType) && isEntityKeyProperty) { ((EntityTypeBase)structuralType).AddKeyMember(member); } } } }
// <summary> // Given the ospace type, returns the fullname of the mapped cspace type. // Today, since we allow non-default mapping between entity type and complex type, // this is only possible for entity and complex type. // </summary> internal static string TryGetMappingCSpaceTypeIdentity(EdmType edmType) { Debug.Assert(DataSpace.OSpace == edmType.DataSpace, "DataSpace must be OSpace"); if (Helper.IsEntityType(edmType)) { return(((ClrEntityType)edmType).CSpaceTypeName); } else if (Helper.IsComplexType(edmType)) { return(((ClrComplexType)edmType).CSpaceTypeName); } else if (Helper.IsEnumType(edmType)) { return(((ClrEnumType)edmType).CSpaceTypeName); } return(edmType.Identity); }
internal virtual void AddLoadedTypes(Dictionary <string, EdmType> typesInLoading) { DebugCheck.NotNull(typesInLoading); var globalItems = new List <GlobalItem>(); foreach (var edmType in typesInLoading.Values) { globalItems.Add(edmType); var cspaceTypeName = ""; try { // Also populate the ocmapping information if (Helper.IsEntityType(edmType)) { cspaceTypeName = ((ClrEntityType)edmType).CSpaceTypeName; _ocMapping.Add(cspaceTypeName, edmType); } else if (Helper.IsComplexType(edmType)) { cspaceTypeName = ((ClrComplexType)edmType).CSpaceTypeName; _ocMapping.Add(cspaceTypeName, edmType); } else if (Helper.IsEnumType(edmType)) { cspaceTypeName = ((ClrEnumType)edmType).CSpaceTypeName; _ocMapping.Add(cspaceTypeName, edmType); } // for the rest of the types like a relationship type, we do not have oc mapping, // so we don't keep that information } catch (ArgumentException e) { throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes(cspaceTypeName), e); } } // Create a new ObjectItemCollection and add all the global items to it. // Also copy all the existing items from the existing collection AddRange(globalItems); }
private static void AddScalarMember( Type type, PropertyInfo clrProperty, StructuralType ospaceType, EdmProperty cspaceProperty, EdmType propertyType) { DebugCheck.NotNull(type); DebugCheck.NotNull(clrProperty); Debug.Assert(clrProperty.CanRead && clrProperty.CanWriteExtended(), "The clr property has to have a setter and a getter."); DebugCheck.NotNull(ospaceType); DebugCheck.NotNull(cspaceProperty); DebugCheck.NotNull(propertyType); Debug.Assert(Helper.IsScalarType(propertyType), "Property has to be primitive or enum."); var cspaceType = cspaceProperty.DeclaringType; var isKeyMember = Helper.IsEntityType(cspaceType) && ((EntityType)cspaceType).KeyMemberNames.Contains(clrProperty.Name); // the property is nullable only if it is not a key and can actually be set to null (i.e. is not a value type or is a nullable value type) var nullableFacetValue = !isKeyMember && (!clrProperty.PropertyType.IsValueType || Nullable.GetUnderlyingType(clrProperty.PropertyType) != null); var ospaceProperty = new EdmProperty( cspaceProperty.Name, TypeUsage.Create( propertyType, new FacetValues { Nullable = nullableFacetValue }), clrProperty, type); if (isKeyMember) { ((EntityType)ospaceType).AddKeyMember(ospaceProperty); } else { ospaceType.AddMember(ospaceProperty); } }
// <summary> // Determines if the given edmType is equal comparable. Consult "EntitySql Language Specification", // section 7 - Comparison and Dependent Operations for details. // </summary> // <param name="edmType"> an instance of an EdmType </param> // <returns> true if edmType is equal-comparable, false otherwise </returns> private static bool IsEqualComparable(EdmType edmType) { if (Helper.IsPrimitiveType(edmType) || Helper.IsRefType(edmType) || Helper.IsEntityType(edmType) || Helper.IsEnumType(edmType)) { return(true); } else if (Helper.IsRowType(edmType)) { var rowType = (RowType)edmType; foreach (var rowProperty in rowType.Properties) { if (!IsEqualComparable(rowProperty.TypeUsage)) { return(false); } } return(true); } return(false); }
// <summary> // determines if type is an EntityType // </summary> internal static bool IsEntityType(TypeUsage type) { return(Helper.IsEntityType(type.EdmType)); }
// <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 new NotSupportedException(Strings.Materializer_UnsupportedType); } ObjectTypeMapping typeMapping; if (Helper.IsPrimitiveType(ospaceType)) { typeMapping = new ObjectTypeMapping(ospaceType, cspaceType); } else { typeMapping = DefaultObjectMappingItemCollection.LoadObjectMapping(cspaceType, ospaceType, null); } return(typeMapping); } }
private static bool IsEqualComparable(EdmType edmType) { if (Helper.IsPrimitiveType(edmType) || Helper.IsRefType((GlobalItem)edmType) || (Helper.IsEntityType(edmType) || Helper.IsEnumType(edmType))) { return(true); } if (!Helper.IsRowType((GlobalItem)edmType)) { return(false); } foreach (EdmMember property in ((RowType)edmType).Properties) { if (!TypeSemantics.IsEqualComparable(property.TypeUsage)) { return(false); } } return(true); }
private void LoadType(Type clrType) { Debug.Assert(clrType.Assembly() == SourceAssembly, "Why are we loading a type that is not in our assembly?"); Debug.Assert(!SessionData.TypesInLoading.ContainsKey(clrType.FullName), "Trying to load a type that is already loaded???"); Debug.Assert(!clrType.IsGenericType(), "Generic type is not supported"); EdmType edmType = null; var typeAttributes = clrType.GetCustomAttributes <EdmTypeAttribute>(inherit: false); // the CLR doesn't allow types to have duplicate/multiple attribute declarations if (typeAttributes.Any()) { if (clrType.IsNested) { SessionData.EdmItemErrors.Add( new EdmItemError(Strings.NestedClassNotSupported(clrType.FullName, clrType.Assembly().FullName))); return; } var typeAttribute = typeAttributes.First(); var cspaceTypeName = String.IsNullOrEmpty(typeAttribute.Name) ? clrType.Name : typeAttribute.Name; if (String.IsNullOrEmpty(typeAttribute.NamespaceName) && clrType.Namespace == null) { SessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_TypeHasNoNamespace)); return; } var cspaceNamespaceName = String.IsNullOrEmpty(typeAttribute.NamespaceName) ? clrType.Namespace : typeAttribute.NamespaceName; if (typeAttribute.GetType() == typeof(EdmEntityTypeAttribute)) { edmType = new ClrEntityType(clrType, cspaceNamespaceName, cspaceTypeName); } else if (typeAttribute.GetType() == typeof(EdmComplexTypeAttribute)) { edmType = new ClrComplexType(clrType, cspaceNamespaceName, cspaceTypeName); } else { Debug.Assert(typeAttribute is EdmEnumTypeAttribute, "Invalid type attribute encountered"); // Note that TryGetPrimitiveType() will return false not only for types that are not primitive // but also for CLR primitive types that are valid underlying enum types in CLR but are not // a valid Edm primitive types (e.g. ulong) PrimitiveType underlyingEnumType; if (!ClrProviderManifest.Instance.TryGetPrimitiveType(clrType.GetEnumUnderlyingType(), out underlyingEnumType)) { SessionData.EdmItemErrors.Add( new EdmItemError( Strings.Validator_UnsupportedEnumUnderlyingType(clrType.GetEnumUnderlyingType().FullName))); return; } edmType = new ClrEnumType(clrType, cspaceNamespaceName, cspaceTypeName); } } else { // not a type we are interested return; } Debug.Assert( !CacheEntry.ContainsType(edmType.Identity), "This type must not be already present in the list of types for this assembly"); // Also add this to the list of the types for this assembly CacheEntry.TypesInAssembly.Add(edmType); // Add this to the known type map so we won't try to load it again SessionData.TypesInLoading.Add(clrType.FullName, edmType); // Load properties for structural type if (Helper.IsStructuralType(edmType)) { //Load base type only for entity type - not sure if we will allow complex type inheritance if (Helper.IsEntityType(edmType)) { TrackClosure(clrType.BaseType()); AddTypeResolver( () => edmType.BaseType = ResolveBaseType(clrType.BaseType())); } // Load the properties for this type LoadPropertiesFromType((StructuralType)edmType); } return; }
private static bool LoadAssemblyFromCache( ObjectItemCollection objectItemCollection, Assembly assembly, bool loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action <String> logLoadMessage) { // Check if its loaded in the cache - if the call is for loading referenced assemblies, make sure that all referenced // assemblies are also loaded KnownAssemblyEntry entry; if (objectItemCollection._knownAssemblies.TryGetKnownAssembly( assembly, objectItemCollection._loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false) { // don't say we loaded anything, unless we actually did before return(entry.CacheEntry.TypesInAssembly.Count != 0); } else if (entry.ReferencedAssembliesAreLoaded) { // this assembly was part of a all hands reference search return(true); } } lock (objectItemCollection.LoadAssemblyLock) { // Check after acquiring the lock, since the known assemblies might have got modified // Check if the assembly is already loaded. The reason we need to check if the assembly is already loaded, is that if (objectItemCollection._knownAssemblies.TryGetKnownAssembly( assembly, objectItemCollection._loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false || entry.ReferencedAssembliesAreLoaded) { return(true); } } Dictionary <string, EdmType> typesInLoading; List <EdmItemError> errors; KnownAssembliesSet knownAssemblies; if (objectItemCollection != null) { knownAssemblies = new KnownAssembliesSet(objectItemCollection._knownAssemblies); } else { knownAssemblies = new KnownAssembliesSet(); } // Load the assembly from the cache AssemblyCache.LoadAssembly( assembly, loadReferencedAssemblies, knownAssemblies, edmItemCollection, logLoadMessage, ref objectItemCollection._loaderCookie, out typesInLoading, out errors); // Throw if we have encountered errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } // We can encounter new assemblies, but they may not have any time in them if (typesInLoading.Count != 0) { // No errors, so go ahead and add the types and make them readonly // The existence of the loading lock tells us whether we should be thread safe or not, if we need // to be thread safe, then we need to use AtomicAddRange. We don't need to actually use the lock // because the caller should have done it already // Recheck the assemblies added, another list is created just to match up the collection type // taken in by AtomicAddRange() var globalItems = new List <GlobalItem>(); foreach (var edmType in typesInLoading.Values) { globalItems.Add(edmType); var cspaceTypeName = ""; try { // Also populate the ocmapping information if (Helper.IsEntityType(edmType)) { cspaceTypeName = ((ClrEntityType)edmType).CSpaceTypeName; objectItemCollection._ocMapping.Add(cspaceTypeName, edmType); } else if (Helper.IsComplexType(edmType)) { cspaceTypeName = ((ClrComplexType)edmType).CSpaceTypeName; objectItemCollection._ocMapping.Add(cspaceTypeName, edmType); } else if (Helper.IsEnumType(edmType)) { cspaceTypeName = ((ClrEnumType)edmType).CSpaceTypeName; objectItemCollection._ocMapping.Add(cspaceTypeName, edmType); } // for the rest of the types like a relationship type, we do not have oc mapping, // so we don't keep that information } catch (ArgumentException e) { throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes(cspaceTypeName), e); } } // Create a new ObjectItemCollection and add all the global items to it. // Also copy all the existing items from the existing collection objectItemCollection.AtomicAddRange(globalItems); } // Update the value of known assemblies objectItemCollection._knownAssemblies = knownAssemblies; foreach (var loadedAssembly in knownAssemblies.Assemblies) { CollectIfViewGenAssembly(loadedAssembly); } return(typesInLoading.Count != 0); } }
// <summary> // Load all the property metadata of the given type // </summary> // <param name="structuralType"> The type where properties are loaded </param> private void LoadPropertiesFromType(StructuralType structuralType) { // Look at both public, internal, and private instanced properties declared at this type, inherited members // are not looked at. Internal and private properties are also looked at because they are also schematized fields var properties = structuralType.ClrType.GetDeclaredProperties().Where(p => !p.IsStatic()); foreach (var property in properties) { EdmMember newMember = null; var isEntityKeyProperty = false; //used for EdmScalarProperties only // EdmScalarPropertyAttribute, EdmComplexPropertyAttribute and EdmRelationshipNavigationPropertyAttribute // are all EdmPropertyAttributes that we need to process. If the current property is not an EdmPropertyAttribute // we will just ignore it and skip to the next property. if (property.GetCustomAttributes <EdmRelationshipNavigationPropertyAttribute>(inherit: false).Any()) { // keep the loop var from being lifted var pi = property; _unresolvedNavigationProperties.Add( () => ResolveNavigationProperty(structuralType, pi)); } else if (property.GetCustomAttributes <EdmScalarPropertyAttribute>(inherit: false).Any()) { if ((Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType).IsEnum()) { TrackClosure(property.PropertyType); var local = property; AddTypeResolver(() => ResolveEnumTypeProperty(structuralType, local)); } else { newMember = LoadScalarProperty(structuralType.ClrType, property, out isEntityKeyProperty); } } else if (property.GetCustomAttributes <EdmComplexPropertyAttribute>(inherit: false).Any()) { TrackClosure(property.PropertyType); // keep loop var from being lifted var local = property; AddTypeResolver(() => ResolveComplexTypeProperty(structuralType, local)); } if (newMember == null) { // Property does not have one of the following attributes: // EdmScalarPropertyAttribute, EdmComplexPropertyAttribute, EdmRelationshipNavigationPropertyAttribute // This means its an unmapped property and can be ignored. // Or there were error encountered while loading the properties continue; } // Add the property object to the type structuralType.AddMember(newMember); // Add to the entity's collection of key members // Do this here instead of in the if condition above for scalar properties because // we want to make sure the AddMember call above did not fail before updating the key members if (Helper.IsEntityType(structuralType) && isEntityKeyProperty) { ((EntityType)structuralType).AddKeyMember(newMember); } } }