Beispiel #1
0
 internal bool TryGetEnumMember(EnumType type, String memberName, bool ignoreCase, out EnumMember outMember)
 {
     EntityUtil.CheckArgumentNull(type, "type");
     EntityUtil.CheckStringArgument(memberName, "memberName");
     outMember = null;
     return type.Members.TryGetValue(memberName, ignoreCase, out outMember);
 }
 internal virtual bool TryGetEnumMember(EnumType type, String memberName, bool ignoreCase, out EnumMember outMember)
 {
     //Contract.Requires(type != null);
     EntityUtil.CheckStringArgument(memberName, "memberName");
     outMember = null;
     return type.Members.TryGetValue(memberName, ignoreCase, out outMember);
 }
        static Converter()
        {
            Debug.Assert(Enum.GetUnderlyingType(typeof(ConcurrencyMode)) == typeof(int), "Please update underlying type below accordingly.");

            // Create the enum types that we will need
            var concurrencyModeType = new EnumType(
                EdmProviderManifest.ConcurrencyModeFacetName,
                EdmConstants.EdmNamespace,
                underlyingType: PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32),
                isFlags: false,
                dataSpace: DataSpace.CSpace);

            foreach (var name in Enum.GetNames(typeof(ConcurrencyMode)))
            {
                concurrencyModeType.AddMember(
                    new EnumMember(
                        name,
                        (int)Enum.Parse(typeof(ConcurrencyMode), name, false)));
            }

            Debug.Assert(
                Enum.GetUnderlyingType(typeof(StoreGeneratedPattern)) == typeof(int), "Please update underlying type below accordingly.");

            var storeGeneratedPatternType = new EnumType(
                EdmProviderManifest.StoreGeneratedPatternFacetName,
                EdmConstants.EdmNamespace,
                underlyingType: PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32),
                isFlags: false,
                dataSpace: DataSpace.CSpace);

            foreach (var name in Enum.GetNames(typeof(StoreGeneratedPattern)))
            {
                storeGeneratedPatternType.AddMember(
                    new EnumMember(
                        name,
                        (int)Enum.Parse(typeof(StoreGeneratedPattern), name, false)));
            }

            // Now create the facet description objects
            ConcurrencyModeFacet = new FacetDescription(
                EdmProviderManifest.ConcurrencyModeFacetName,
                concurrencyModeType,
                null,
                null,
                ConcurrencyMode.None);
            StoreGeneratedPatternFacet = new FacetDescription(
                EdmProviderManifest.StoreGeneratedPatternFacetName,
                storeGeneratedPatternType,
                null,
                null,
                StoreGeneratedPattern.None);
            CollationFacet = new FacetDescription(
                DbProviderManifest.CollationFacetName,
                MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.String),
                null,
                null,
                string.Empty);
        }
        /// <summary>
        /// Converts SchemaEnumType instance to Metadata EnumType.
        /// </summary>
        /// <param name="somEnumType">SchemaEnumType to be covnerted.</param>
        /// <param name="newGlobalItems">Global item objects where newly created Metadata EnumType will be added.</param>
        /// <returns></returns>
        private static EnumType ConvertToEnumType(Som.SchemaEnumType somEnumType, Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            Debug.Assert(somEnumType != null, "somEnumType != null");
            Debug.Assert(newGlobalItems != null, "newGlobalItems != null");
            Debug.Assert(somEnumType.UnderlyingType is Som.ScalarType, "At this point the underlying type should have already been validated and should be ScalarType");

            Som.ScalarType enumUnderlyingType = (Som.ScalarType)somEnumType.UnderlyingType;

            // note that enums don't live in SSpace so there is no need to GetDataSpace() for it.
            EnumType enumType = new EnumType(somEnumType.Name,
                                             somEnumType.Namespace,
                                             enumUnderlyingType.Type,
                                             somEnumType.IsFlags,
                                             DataSpace.CSpace);

            Type clrEnumUnderlyingType = enumUnderlyingType.Type.ClrEquivalentType;

            foreach (var somEnumMember in somEnumType.EnumMembers)
            {
                Debug.Assert(somEnumMember.Value != null, "value must not be null at this point");
                var enumMember = new EnumMember(somEnumMember.Name, Convert.ChangeType(somEnumMember.Value, clrEnumUnderlyingType, CultureInfo.InvariantCulture));

                if (somEnumMember.Documentation != null)
                {
                    enumMember.Documentation = ConvertToDocumentation(somEnumMember.Documentation);
                }

                AddOtherContent(somEnumMember, enumMember);
                enumType.AddMember(enumMember);
            }

            if (somEnumType.Documentation != null)
            {
                enumType.Documentation = ConvertToDocumentation(somEnumType.Documentation);
            }
            AddOtherContent(somEnumType, enumType);

            newGlobalItems.Add(somEnumType, enumType);
            return enumType;
        }
        /// <summary>
        /// Verifies whether enum members of CLR and EDM types match.
        /// </summary>
        /// <param name="enumType">OSpace CLR enum type.</param>
        /// <param name="cspaceEnumType">CSpace EDM enum type.</param>
        /// <returns><c>true</c> if members match. <c>false</c> otherwise.</returns>
        private bool EnumMembersMatch(Type enumType, EnumType cspaceEnumType)
        {
            Debug.Assert(enumType != null, "enumType != null");
            Debug.Assert(enumType.IsEnum, "expected enum OSpace type");
            Debug.Assert(cspaceEnumType != null, "cspaceEnumType != null");
            Debug.Assert(Helper.IsEnumType(cspaceEnumType), "Enum type expected");
            Debug.Assert(cspaceEnumType.UnderlyingType.ClrEquivalentType == enumType.GetEnumUnderlyingType(), "underlying types should have already been checked");

            var enumUnderlyingType = enumType.GetEnumUnderlyingType();

            var cspaceSortedEnumMemberEnumerator = cspaceEnumType.Members.OrderBy(m => m.Name).GetEnumerator();
            var ospaceSortedEnumMemberNamesEnumerator = enumType.GetEnumNames().OrderBy(n => n).GetEnumerator();

            // no checks required if edm enum type does not have any members 
            if (!cspaceSortedEnumMemberEnumerator.MoveNext())
            {
                return true;
            }

            while (ospaceSortedEnumMemberNamesEnumerator.MoveNext())
            {
                if (cspaceSortedEnumMemberEnumerator.Current.Name == ospaceSortedEnumMemberNamesEnumerator.Current &&
                    cspaceSortedEnumMemberEnumerator.Current.Value.Equals(
                        Convert.ChangeType(
                            Enum.Parse(enumType, ospaceSortedEnumMemberNamesEnumerator.Current), enumUnderlyingType, CultureInfo.InvariantCulture)))
                {
                    if (!cspaceSortedEnumMemberEnumerator.MoveNext())
                    {
                        return true;
                    }
                }
            }

            SessionData.LoadMessageLogger.LogLoadMessage(
                System.Data.Entity.Strings.Mapping_Enum_OCMapping_MemberMismatch(
                        enumType.FullName,
                        cspaceSortedEnumMemberEnumerator.Current.Name,
                        cspaceSortedEnumMemberEnumerator.Current.Value,
                        cspaceEnumType.FullName), cspaceEnumType);
                
            return false;
        }
        /// <summary>
        /// Verifies whether underlying types of CLR and EDM types match
        /// </summary>
        /// <param name="enumType">OSpace CLR enum type.</param>
        /// <param name="cspaceEnumType">CSpace EDM enum type.</param>
        /// <returns><c>true</c> if types match. <c>false</c> otherwise.</returns>
        private bool UnderlyingEnumTypesMatch(Type enumType, EnumType cspaceEnumType)
        {
            Debug.Assert(enumType != null, "enumType != null");
            Debug.Assert(enumType.IsEnum, "expected enum OSpace type");
            Debug.Assert(cspaceEnumType != null, "cspaceEnumType != null");
            Debug.Assert(Helper.IsEnumType(cspaceEnumType), "Enum type expected");

            // 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(enumType.GetEnumUnderlyingType(), out underlyingEnumType))
            {
                SessionData.LoadMessageLogger.LogLoadMessage(
                    Strings.Validator_UnsupportedEnumUnderlyingType(enumType.GetEnumUnderlyingType().FullName), 
                    cspaceEnumType);

                return false;
            }
            else if (underlyingEnumType.PrimitiveTypeKind != cspaceEnumType.UnderlyingType.PrimitiveTypeKind)
            {
                SessionData.LoadMessageLogger.LogLoadMessage(
                    Strings.Validator_OSpace_Convention_NonMatchingUnderlyingTypes, cspaceEnumType);

                return false;
            }

            return true;
        }
        /// <summary>
        /// Creates new enum OSpace type built based on CLR <paramref name="enumType"/> and <paramref name="cspaceEnumType"/>
        /// </summary>
        /// <param name="enumType">CLR type to create OSpace type from.</param>
        /// <param name="cspaceEnumType">CSpace type used to get namespace and name for the newly created OSpace type.</param>
        /// <param name="newOSpaceType">
        /// New enum OSpace type built based on CLR <paramref name="enumType"/> and <paramref name="cspaceEnumType"/> or null
        /// if the type could not be built.
        /// </param>
        /// <returns><c>true</c> if the type was built successfully.<c>false</c> otherwise.</returns>
        private bool TryCreateEnumType(Type enumType, EnumType cspaceEnumType, out EdmType newOSpaceType)
        {
            Debug.Assert(enumType != null, "enumType != null");
            Debug.Assert(enumType.IsEnum, "enum type expected");
            Debug.Assert(cspaceEnumType != null, "cspaceEnumType != null");
            Debug.Assert(Helper.IsEnumType(cspaceEnumType), "Enum type expected");
            Debug.Assert(TypesMatchByConvention(enumType, cspaceEnumType), "The types passed as parameters don't match by convention.");

            newOSpaceType = null;

            // Check if the OSpace and CSpace enum type match
            if (!UnderlyingEnumTypesMatch(enumType, cspaceEnumType) || !EnumMembersMatch(enumType, cspaceEnumType))
            {
                return false;
            }

            newOSpaceType = new ClrEnumType(enumType, cspaceEnumType.NamespaceName, cspaceEnumType.Name);
            SessionData.TypesInLoading.Add(enumType.FullName, newOSpaceType);

            return true;
        }
        protected override void Visit(EnumType enumType)
        {
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(enumType, out index))
            {
                return;
            }

            this.AddObjectStartDumpToHashBuilder(enumType, index);

            this.AddObjectContentToHashBuilder(enumType.Identity);
            this.Visit(enumType.UnderlyingType);

            base.Visit(enumType);

            this.AddObjectEndDumpToHashBuilder();
        }
 protected virtual void Visit(EnumType enumType)
 {
     foreach (var member in enumType.Members)
     {
         Visit(member);
     }
 }
        /// <summary>
        /// Validates whether CSpace enum type and OSpace enum type match.
        /// </summary>
        /// <param name="edmEnumType">CSpace enum type.</param>
        /// <param name="objectEnumType">OSpace enum type.</param>
        private static void ValidateEnumTypeMapping(EnumType edmEnumType, EnumType objectEnumType)
        {
            Debug.Assert(edmEnumType != null, "edmEnumType != null");
            Debug.Assert(Helper.IsPrimitiveType(edmEnumType.UnderlyingType));
            Debug.Assert(Helper.IsSupportedEnumUnderlyingType(edmEnumType.UnderlyingType.PrimitiveTypeKind));

            Debug.Assert(objectEnumType != null, "objectEnumType != null");
            Debug.Assert(Helper.IsPrimitiveType(objectEnumType.UnderlyingType));
            Debug.Assert(Helper.IsSupportedEnumUnderlyingType(objectEnumType.UnderlyingType.PrimitiveTypeKind));

            if (edmEnumType.UnderlyingType.PrimitiveTypeKind != objectEnumType.UnderlyingType.PrimitiveTypeKind)
            {
                throw new MappingException(
                    System.Data.Entity.Strings.Mapping_Enum_OCMapping_UnderlyingTypesMismatch(
                        edmEnumType.UnderlyingType.Name, 
                        edmEnumType.FullName,
                        objectEnumType.UnderlyingType.Name,
                        objectEnumType.FullName));
            }

            // EnumMember.Value is just a number so sorting by value is faster than by the name. 
            // The drawback is that there can be multiple members with the same value. To break 
            // the tie we need to sort by name after sorting by value.
            var edmEnumTypeMembersSortedEnumerator =
                edmEnumType.Members.OrderBy(m => Convert.ToInt64(m.Value, CultureInfo.InvariantCulture)).ThenBy(m => m.Name).GetEnumerator();
            var objectEnumTypeMembersSortedEnumerator =
                objectEnumType.Members.OrderBy(m => Convert.ToInt64(m.Value, CultureInfo.InvariantCulture)).ThenBy(m => m.Name).GetEnumerator();

            if (edmEnumTypeMembersSortedEnumerator.MoveNext())
            {
                while (objectEnumTypeMembersSortedEnumerator.MoveNext())
                {
                    if (edmEnumTypeMembersSortedEnumerator.Current.Name == objectEnumTypeMembersSortedEnumerator.Current.Name &&
                        edmEnumTypeMembersSortedEnumerator.Current.Value.Equals(objectEnumTypeMembersSortedEnumerator.Current.Value))
                    {
                        if (!edmEnumTypeMembersSortedEnumerator.MoveNext())
                        {
                            return;
                        }
                    }
                }

                throw new MappingException(
                    System.Data.Entity.Strings.Mapping_Enum_OCMapping_MemberMismatch(
                        objectEnumType.FullName,
                        edmEnumTypeMembersSortedEnumerator.Current.Name,
                        edmEnumTypeMembersSortedEnumerator.Current.Value,
                        edmEnumType.FullName));
            }
        }
 internal Type GetClrType(EnumType enumType) {
     var objectSpaceType = (EnumType)_context.MetadataWorkspace.GetObjectSpaceType(enumType);
     return _objectSpaceItems.GetClrType(objectSpaceType);
 }
 public virtual Type GetClrType(EnumType item)
 {
     return _objectItemCollection.GetClrType(item);
 }
 /// <summary>
 /// The method returns the underlying CLR type for the specified OSpace enum 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>
 public bool TryGetClrType(EnumType objectSpaceType, out Type clrType)
 {
     return(ObjectItemCollection.TryGetClrType((EdmType)objectSpaceType, out clrType));
 }
 /// <summary>
 /// The method returns the underlying CLR type for the specified OSpace type argument.
 /// If the DataSpace of the parameter is not OSpace, an ArgumentException is thrown.
 /// </summary>
 /// <param name="objectSpaceType">The OSpace type to look up</param>
 /// <returns>The CLR type of the OSpace argument</returns>
 public Type GetClrType(EnumType objectSpaceType)
 {
     return(ObjectItemCollection.GetClrType((EdmType)objectSpaceType));
 }