예제 #1
0
        /// <summary>
        /// Computes the closure of common super types of the set of predefined edm primitive types
        /// This is done only once and cached as opposed to previous implementation that was computing
        /// this for every new pair of types.
        /// </summary>
        private static void ComputeCommonTypeClosure()
        {
            if (null != _commonTypeClosure)
            {
                return;
            }

            objectModel.ReadOnlyCollection <PrimitiveType>[,] commonTypeClosure = new objectModel.ReadOnlyCollection <PrimitiveType> [EdmConstants.NumPrimitiveTypes, EdmConstants.NumPrimitiveTypes];
            for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
            {
                commonTypeClosure[i, i] = Helper.EmptyPrimitiveTypeReadOnlyCollection;
            }

            objectModel.ReadOnlyCollection <PrimitiveType> primitiveTypes = EdmProviderManifest.Instance.GetStoreTypes();

            for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    commonTypeClosure[i, j] = Intersect(EdmProviderManifest.Instance.GetPromotionTypes(primitiveTypes[i]),
                                                        EdmProviderManifest.Instance.GetPromotionTypes(primitiveTypes[j]));

                    commonTypeClosure[j, i] = commonTypeClosure[i, j];
                }
            }

            TypeSemantics.AssertTypeInvariant("Common Type closure is incorrect",
                                              delegate()
            {
                for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
                {
                    for (int j = 0; j < EdmConstants.NumPrimitiveTypes; j++)
                    {
                        if (commonTypeClosure[i, j] != commonTypeClosure[j, i])
                        {
                            return(false);
                        }
                        if (i == j && commonTypeClosure[i, j].Count != 0)
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            });

            System.Threading.Interlocked.CompareExchange <objectModel.ReadOnlyCollection <PrimitiveType> [, ]>(ref _commonTypeClosure, commonTypeClosure, null);
        }
예제 #2
0
        /// <summary>
        /// Validates whether cspace and sspace types are compatible.
        /// </summary>
        /// <param name="cspaceType">Type in C-Space. Must be a primitive or enumeration type.</param>
        /// <param name="storeType">C-Space equivalent of S-space Type. Must be a primitive type.</param>
        /// <returns>
        /// <c>true</c> if the types are compatible. <c>false</c> otherwise.
        /// </returns>
        /// <remarks>
        /// This methods validate whether cspace and sspace types are compatible. The types are
        /// compatible if:
        /// both are primitive and the cspace type is a subtype of sspace type
        /// or
        /// cspace type is an enumeration type whose underlying type is a subtype of sspace type.
        /// </remarks>
        private static bool ValidateScalarTypesAreCompatible(TypeUsage cspaceType, TypeUsage storeType)
        {
            Debug.Assert(cspaceType != null, "cspaceType != null");
            Debug.Assert(storeType != null, "storeType != null");
            Debug.Assert(cspaceType.EdmType.DataSpace == DataSpace.CSpace, "cspace property must have a cspace type");
            Debug.Assert(storeType.EdmType.DataSpace == DataSpace.CSpace, "storeType type usage must have a sspace type");
            Debug.Assert(
                Helper.IsScalarType(cspaceType.EdmType),
                "cspace property must be of a primitive or enumeration type");
            Debug.Assert(Helper.IsPrimitiveType(storeType.EdmType), "storeType property must be a primitive type");

            if (Helper.IsEnumType(cspaceType.EdmType))
            {
                // For enum cspace type check whether its underlying type is a subtype of the store type. Note that
                // TypeSemantics.IsSubTypeOf uses only TypeUsage.EdmType for primitive types so there is no need to copy facets
                // from the enum type property to the underlying type TypeUsage created here since they wouldn't be used anyways.
                return(TypeSemantics.IsSubTypeOf(TypeUsage.Create(Helper.GetUnderlyingEdmTypeForEnumType(cspaceType.EdmType)), storeType));
            }

            return(TypeSemantics.IsSubTypeOf(cspaceType, storeType));
        }
예제 #3
0
        /// <summary>
        /// Returns a Model type usage for a provider type
        /// </summary>
        /// <returns>model (CSpace) type usage</returns>
        internal TypeUsage GetModelTypeUsage()
        {
            if (_modelTypeUsage == null)
            {
                EdmType edmType = this.EdmType;

                // If the edm type is already a cspace type, return the same type
                if (edmType.DataSpace == DataSpace.CSpace || edmType.DataSpace == DataSpace.OSpace)
                {
                    return(this);
                }

                TypeUsage result;
                if (Helper.IsRowType(edmType))
                {
                    RowType       sspaceRowType = (RowType)edmType;
                    EdmProperty[] properties    = new EdmProperty[sspaceRowType.Properties.Count];
                    for (int i = 0; i < properties.Length; i++)
                    {
                        EdmProperty sspaceProperty = sspaceRowType.Properties[i];
                        TypeUsage   newTypeUsage   = sspaceProperty.TypeUsage.GetModelTypeUsage();
                        properties[i] = new EdmProperty(sspaceProperty.Name, newTypeUsage);
                    }
                    RowType edmRowType = new RowType(properties, sspaceRowType.InitializerMetadata);
                    result = TypeUsage.Create(edmRowType, this.Facets);
                }
                else if (Helper.IsCollectionType(edmType))
                {
                    CollectionType sspaceCollectionType = ((CollectionType)edmType);
                    TypeUsage      newTypeUsage         = sspaceCollectionType.TypeUsage.GetModelTypeUsage();
                    result = TypeUsage.Create(new CollectionType(newTypeUsage), this.Facets);
                }
                else if (Helper.IsRefType(edmType))
                {
                    System.Diagnostics.Debug.Assert(((RefType)edmType).ElementType.DataSpace == DataSpace.CSpace);
                    result = this;
                }
                else if (Helper.IsPrimitiveType(edmType))
                {
                    result = ((PrimitiveType)edmType).ProviderManifest.GetEdmType(this);

                    if (result == null)
                    {
                        throw EntityUtil.ProviderIncompatible(System.Data.Entity.Strings.Mapping_ProviderReturnsNullType(this.ToString()));
                    }

                    if (!TypeSemantics.IsNullable(this))
                    {
                        result = TypeUsage.Create(result.EdmType,
                                                  OverrideFacetValues(result.Facets,
                                                                      new FacetValues {
                            Nullable = false
                        }));
                    }
                }
                else if (Helper.IsEntityTypeBase(edmType) || Helper.IsComplexType(edmType))
                {
                    result = this;
                }
                else
                {
                    System.Diagnostics.Debug.Assert(false, "Unexpected type found in entity data reader");
                    return(null);
                }
                System.Threading.Interlocked.CompareExchange(ref _modelTypeUsage, result, null);
            }
            return(_modelTypeUsage);
        }
예제 #4
0
 /// <summary>
 /// determines if type is of Boolean Kind
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 internal static bool IsBooleanType(TypeUsage type)
 {
     return(TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Boolean));
 }