コード例 #1
0
        // <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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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));
        }
コード例 #5
0
 internal static bool IsEntityTypeBase(EdmType edmType)
 {
     if (!Helper.IsEntityType(edmType))
     {
         return(Helper.IsRelationshipType(edmType));
     }
     return(true);
 }
コード例 #6
0
 internal static bool IsStructuralType(EdmType type)
 {
     if (!Helper.IsComplexType(type) && !Helper.IsEntityType(type) && !Helper.IsRelationshipType(type))
     {
         return(Helper.IsRowType((GlobalItem)type));
     }
     return(true);
 }
コード例 #7
0
 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));
 }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        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);
                }
            }
        }
コード例 #10
0
 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);
 }
コード例 #11
0
        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);
                        }
                    }
                }
            }
        }
コード例 #12
0
        // <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));
        }
コード例 #13
0
 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);
 }
コード例 #14
0
 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);
             }
         }
     }
 }
コード例 #15
0
        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);
        }
コード例 #16
0
 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);
             }
         }
     }
 }
コード例 #17
0
        // <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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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);
            }
        }
コード例 #20
0
 // <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);
 }
コード例 #21
0
 // <summary>
 // determines if type is an EntityType
 // </summary>
 internal static bool IsEntityType(TypeUsage type)
 {
     return(Helper.IsEntityType(type.EdmType));
 }
コード例 #22
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 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);
            }
        }
コード例 #23
0
 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;
        }
コード例 #25
0
        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);
                }
            }
        }