Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Metadata / Edm / TypeUsage.cs / 1 / TypeUsage.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.Text; using System.Data.Common.Utils; using System.Linq; namespace System.Data.Metadata.Edm { ////// Class representing a type information for an item /// [DebuggerDisplay("EdmType={EdmType}, Facets.Count={Facets.Count}")] public sealed class TypeUsage : MetadataItem { #region Constructors ////// The constructor for TypeUsage taking in a type /// /// The type which the TypeUsage object describes ///Thrown if edmType argument is null private TypeUsage(EdmType edmType) :base(MetadataFlags.Readonly) { EntityUtil.GenericCheckArgumentNull(edmType, "edmType"); _edmType = edmType; // I would like to be able to assert that the edmType is ReadOnly, but // because some types are still in loading while the TypeUsage is being created // that won't work. We should consider a way to change this } ////// The constructor for TypeUsage taking in a type and a collection of facets /// /// The type which the TypeUsage object describes /// The replacement collection of facets ///Thrown if edmType argument is null private TypeUsage(EdmType edmType, IEnumerablefacets) : this(edmType) { MetadataCollection facetCollection = new MetadataCollection (facets); facetCollection.SetReadOnly(); _facets = facetCollection.AsReadOnlyMetadataCollection(); } #endregion #region Factory Methods /// /// Factory method for creating a TypeUsage with specified EdmType /// /// EdmType for which to create a type usage ///new TypeUsage instance with default facet values internal static TypeUsage Create(EdmType edmType) { return new TypeUsage(edmType); } ////// Factory method for creating a TypeUsage with specified EdmType /// /// EdmType for which to create a type usage ///new TypeUsage instance with default facet values internal static TypeUsage Create(EdmType edmType, FacetValues values) { return new TypeUsage(edmType, GetDefaultFacetDescriptionsAndOverrideFacetValues(edmType, values)); } ////// Factory method for creating a TypeUsage with specified EdmType and facets /// /// EdmType for which to create a type usage /// facets to be copied into the new TypeUsage ///new TypeUsage instance internal static TypeUsage Create(EdmType edmType, IEnumerablefacets) { return new TypeUsage(edmType, facets); } internal TypeUsage ShallowCopy(FacetValues facetValues) { return TypeUsage.Create(_edmType, OverrideFacetValues(Facets, facetValues)); } /// /// Factory method for creating a "readonly" TypeUsage with specified EdmType /// /// An EdmType for which to create a TypeUsage ///A TypeUsage instance with default facet values for the specified EdmType [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "0#edm")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")] public static TypeUsage CreateDefaultTypeUsage(EdmType edmType) { EntityUtil.CheckArgumentNull(edmType, "edmType"); TypeUsage type = TypeUsage.Create(edmType); return type; } /// /// Factory method for creating a string TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct the TypeUsage /// Whether the string type is unicode or not /// Whether the string type is fixed length or not /// The max length of the string type ///A TypeUsage object describing a string type with the given facet values public static TypeUsage CreateStringTypeUsage(PrimitiveType primitiveType, bool isUnicode, bool isFixedLength, int maxLength) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.String) { throw EntityUtil.NotStringTypeForTypeUsage(); } ValidateMaxLength(maxLength); TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ MaxLength = maxLength, Unicode = isUnicode, FixedLength = isFixedLength}); return typeUsage; } /// /// Factory method for creating a string TypeUsage object with the specified facets and /// unbounded MaxLength /// /// A PrimitiveType for which to construct the TypeUsage /// Whether the string type is unicode or not /// Whether the string type is fixed length or not ///A TypeUsage object describing a string type with the given facet values /// and unbounded MaxLength public static TypeUsage CreateStringTypeUsage(PrimitiveType primitiveType, bool isUnicode, bool isFixedLength) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.String) { throw EntityUtil.NotStringTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ MaxLength = TypeUsage.DefaultMaxLengthFacetValue, Unicode = isUnicode, FixedLength = isFixedLength}); return typeUsage; } /// /// Factory method for creating a Binary TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct TypeUsage /// Whether the binary type is fixed length or not /// The max length of the binary type ///A TypeUsage object describing a binary type with the given facet values public static TypeUsage CreateBinaryTypeUsage(PrimitiveType primitiveType, bool isFixedLength, int maxLength) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Binary) { throw EntityUtil.NotBinaryTypeForTypeUsage(); } ValidateMaxLength(maxLength); TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{MaxLength = maxLength, FixedLength = isFixedLength}); return typeUsage; } /// /// Factory method for creating a Binary TypeUsage object with the specified facets and /// unbounded MaxLength /// /// A PrimitiveType for which to construct the TypeUsage /// Whether the binary type is fixed length or not ///A TypeUsage object describing a binary type with the given facet values public static TypeUsage CreateBinaryTypeUsage(PrimitiveType primitiveType, bool isFixedLength) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Binary) { throw EntityUtil.NotBinaryTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{MaxLength = TypeUsage.DefaultMaxLengthFacetValue, FixedLength = isFixedLength}); return typeUsage; } /// /// Factory method for creating a DateTime TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct the TypeUsage /// Precision for seconds ///A TypeUsage object describing a DateTime type with the given facet values public static TypeUsage CreateDateTimeTypeUsage(PrimitiveType primitiveType, byte? precision) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.DateTime) { throw EntityUtil.NotDateTimeTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{Precision = precision}); return typeUsage; } /// /// Factory method for creating a DateTimeOffset TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct the TypeUsage /// Precision for seconds ///A TypeUsage object describing a DateTime type with the given facet values public static TypeUsage CreateDateTimeOffsetTypeUsage(PrimitiveType primitiveType, byte? precision) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.DateTimeOffset) { throw EntityUtil.NotDateTimeOffsetTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ Precision = precision }); return typeUsage; } /// /// Factory method for creating a Time TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct the TypeUsage /// Precision for seconds ///A TypeUsage object describing a Time type with the given facet values public static TypeUsage CreateTimeTypeUsage(PrimitiveType primitiveType, byte? precision) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Time) { throw EntityUtil.NotTimeTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ Precision = precision }); return typeUsage; } /// /// Factory method for creating a Decimal TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct type usage /// The precision of the decimal type /// The scale of the decimal type ///A TypeUsage object describing a decimal type with the given facet values public static TypeUsage CreateDecimalTypeUsage(PrimitiveType primitiveType, byte precision, byte scale) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Decimal) { throw EntityUtil.NotDecimalTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{Precision = precision, Scale = scale }); return typeUsage; } /// /// Factory method for creating a Decimal TypeUsage object with unbounded precision and scale /// /// The PrimitiveType for which to construct type usage ///A TypeUsage object describing a decimal type with unbounded precision and scale public static TypeUsage CreateDecimalTypeUsage(PrimitiveType primitiveType) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Decimal) { throw EntityUtil.NotDecimalTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ Precision = TypeUsage.DefaultPrecisionFacetValue, Scale = TypeUsage.DefaultScaleFacetValue }); return typeUsage; } #endregion #region Fields private TypeUsage _modelTypeUsage; private readonly EdmType _edmType; private ReadOnlyMetadataCollection _facets; private string _identity; /// /// Set of facets that should be included in identity for TypeUsage /// ///keep this sorted for binary searching private static readonly string[] s_identityFacets = new string[] { DbProviderManifest.DefaultValueFacetName, DbProviderManifest.FixedLengthFacetName, DbProviderManifest.MaxLengthFacetName, DbProviderManifest.NullableFacetName, DbProviderManifest.PrecisionFacetName, DbProviderManifest.ScaleFacetName, DbProviderManifest.UnicodeFacetName, }; internal static readonly EdmConstants.Unbounded DefaultMaxLengthFacetValue = EdmConstants.UnboundedValue; internal static readonly EdmConstants.Unbounded DefaultPrecisionFacetValue = EdmConstants.UnboundedValue; internal static readonly EdmConstants.Unbounded DefaultScaleFacetValue = EdmConstants.UnboundedValue; internal static readonly bool DefaultUnicodeFacetValue = true; internal static readonly bool DefaultFixedLengthFacetValue = false; internal static readonly byte? DefaultDateTimePrecisionFacetValue = null; #endregion #region Properties ////// Returns the kind of the type /// public override BuiltInTypeKind BuiltInTypeKind { get { return BuiltInTypeKind.TypeUsage; } } ////// Gets the type that this TypeUsage describes /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] [MetadataProperty(BuiltInTypeKind.EdmType, false)] public EdmType EdmType { get { return _edmType; } } ////// Gets the list of facets for the type in this TypeUsage /// [MetadataProperty(BuiltInTypeKind.Facet, true)] public ReadOnlyMetadataCollectionFacets { get { if (null == _facets) { MetadataCollection facets = new MetadataCollection (GetFacets()); // we never modify the collection so we can set it readonly from the start facets.SetReadOnly(); System.Threading.Interlocked.CompareExchange(ref _facets, facets.AsReadOnlyMetadataCollection(), null); } return _facets; } } #endregion #region Methods /// /// Returns a Model type usage for a provider type /// ///model (CSpace) type usage 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; } ////// check if "this" is a subtype of the specified TypeUsage /// /// The typeUsage to be checked ///true if this typeUsage is a subtype of the specified typeUsage public bool IsSubtypeOf(TypeUsage typeUsage) { if (EdmType == null || typeUsage == null) { return false; } return EdmType.IsSubtypeOf(typeUsage.EdmType); } private IEnumerableGetFacets() { foreach (FacetDescription facetDescription in _edmType.GetAssociatedFacetDescriptions()) { yield return facetDescription.DefaultValueFacet; } } internal override void SetReadOnly() { Debug.Fail("TypeUsage.SetReadOnly should not need to ever be called"); base.SetReadOnly(); } /// /// returns the identity of the type usage /// internal override String Identity { get { if (this.Facets.Count == 0) { return this.EdmType.Identity; } if (this._identity == null) { StringBuilder builder = new StringBuilder(128); BuildIdentity(builder); string identity = builder.ToString(); System.Threading.Interlocked.CompareExchange(ref _identity, identity, null); } return this._identity; } } private static IEnumerableGetDefaultFacetDescriptionsAndOverrideFacetValues(EdmType type, FacetValues values) { return OverrideFacetValues(type.GetAssociatedFacetDescriptions(), fd => fd, fd => fd.DefaultValueFacet, values); } private static IEnumerable OverrideFacetValues(IEnumerable facets, FacetValues values) { return OverrideFacetValues(facets, f => f.Description, f => f, values); } private static IEnumerable OverrideFacetValues (IEnumerable facetThings, Func getDescription, Func getFacet, FacetValues values) { // yield all the non custom values foreach (var thing in facetThings) { FacetDescription description = getDescription(thing); Facet facet; if (!description.IsConstant && values.TryGetFacet(description, out facet)) { yield return facet; } else { yield return getFacet(thing); } } } internal override void BuildIdentity(StringBuilder builder) { // if we've already cached the identity, simply append it if (null != _identity) { builder.Append(_identity); return; } builder.Append(this.EdmType.Identity); builder.Append("("); bool first = true; for (int j = 0; j < this.Facets.Count; j++) { Facet facet = this.Facets[j]; if (0 <= Array.BinarySearch(s_identityFacets, facet.Name, StringComparer.Ordinal)) { if (first) { first = false; } else { builder.Append(","); } builder.Append(facet.Name); builder.Append("="); // If the facet is present, add its value to the identity // We only include built-in system facets for the identity builder.Append(facet.Value ?? String.Empty); } } builder.Append(")"); } /// /// public override string ToString() { return EdmType.ToString(); } ////// EdmEquals override verifying the equivalence of all facets. Two facets are considered /// equal if they have the same name and the same value (Object.Equals) /// /// ///internal override bool EdmEquals(MetadataItem item) { // short-circuit if this and other are reference equivalent if (Object.ReferenceEquals(this, item)) { return true; } // check type of item if (null == item || BuiltInTypeKind.TypeUsage != item.BuiltInTypeKind) { return false; } TypeUsage other = (TypeUsage)item; // verify edm types are equivalent if (!this.EdmType.EdmEquals(other.EdmType)) { return false; } // if both usages have default facets, no need to compare if (null == this._facets && null == other._facets) { return true; } // initialize facets and compare if (this.Facets.Count != other.Facets.Count) { return false; } foreach (Facet thisFacet in this.Facets) { Facet otherFacet; if (!other.Facets.TryGetValue(thisFacet.Name, false, out otherFacet)) { // other type usage doesn't have the same facets as this type usage return false; } // check that the facet values are the same if (!Object.Equals(thisFacet.Value, otherFacet.Value)) { return false; } } return true; } private static void ValidateMaxLength(int maxLength) { if (maxLength <= 0) { throw EntityUtil.ArgumentOutOfRange(System.Data.Entity.Strings.InvalidMaxLengthSize, "maxLength"); } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.Text; using System.Data.Common.Utils; using System.Linq; namespace System.Data.Metadata.Edm { ////// Class representing a type information for an item /// [DebuggerDisplay("EdmType={EdmType}, Facets.Count={Facets.Count}")] public sealed class TypeUsage : MetadataItem { #region Constructors ////// The constructor for TypeUsage taking in a type /// /// The type which the TypeUsage object describes ///Thrown if edmType argument is null private TypeUsage(EdmType edmType) :base(MetadataFlags.Readonly) { EntityUtil.GenericCheckArgumentNull(edmType, "edmType"); _edmType = edmType; // I would like to be able to assert that the edmType is ReadOnly, but // because some types are still in loading while the TypeUsage is being created // that won't work. We should consider a way to change this } ////// The constructor for TypeUsage taking in a type and a collection of facets /// /// The type which the TypeUsage object describes /// The replacement collection of facets ///Thrown if edmType argument is null private TypeUsage(EdmType edmType, IEnumerablefacets) : this(edmType) { MetadataCollection facetCollection = new MetadataCollection (facets); facetCollection.SetReadOnly(); _facets = facetCollection.AsReadOnlyMetadataCollection(); } #endregion #region Factory Methods /// /// Factory method for creating a TypeUsage with specified EdmType /// /// EdmType for which to create a type usage ///new TypeUsage instance with default facet values internal static TypeUsage Create(EdmType edmType) { return new TypeUsage(edmType); } ////// Factory method for creating a TypeUsage with specified EdmType /// /// EdmType for which to create a type usage ///new TypeUsage instance with default facet values internal static TypeUsage Create(EdmType edmType, FacetValues values) { return new TypeUsage(edmType, GetDefaultFacetDescriptionsAndOverrideFacetValues(edmType, values)); } ////// Factory method for creating a TypeUsage with specified EdmType and facets /// /// EdmType for which to create a type usage /// facets to be copied into the new TypeUsage ///new TypeUsage instance internal static TypeUsage Create(EdmType edmType, IEnumerablefacets) { return new TypeUsage(edmType, facets); } internal TypeUsage ShallowCopy(FacetValues facetValues) { return TypeUsage.Create(_edmType, OverrideFacetValues(Facets, facetValues)); } /// /// Factory method for creating a "readonly" TypeUsage with specified EdmType /// /// An EdmType for which to create a TypeUsage ///A TypeUsage instance with default facet values for the specified EdmType [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "0#edm")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")] public static TypeUsage CreateDefaultTypeUsage(EdmType edmType) { EntityUtil.CheckArgumentNull(edmType, "edmType"); TypeUsage type = TypeUsage.Create(edmType); return type; } /// /// Factory method for creating a string TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct the TypeUsage /// Whether the string type is unicode or not /// Whether the string type is fixed length or not /// The max length of the string type ///A TypeUsage object describing a string type with the given facet values public static TypeUsage CreateStringTypeUsage(PrimitiveType primitiveType, bool isUnicode, bool isFixedLength, int maxLength) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.String) { throw EntityUtil.NotStringTypeForTypeUsage(); } ValidateMaxLength(maxLength); TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ MaxLength = maxLength, Unicode = isUnicode, FixedLength = isFixedLength}); return typeUsage; } /// /// Factory method for creating a string TypeUsage object with the specified facets and /// unbounded MaxLength /// /// A PrimitiveType for which to construct the TypeUsage /// Whether the string type is unicode or not /// Whether the string type is fixed length or not ///A TypeUsage object describing a string type with the given facet values /// and unbounded MaxLength public static TypeUsage CreateStringTypeUsage(PrimitiveType primitiveType, bool isUnicode, bool isFixedLength) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.String) { throw EntityUtil.NotStringTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ MaxLength = TypeUsage.DefaultMaxLengthFacetValue, Unicode = isUnicode, FixedLength = isFixedLength}); return typeUsage; } /// /// Factory method for creating a Binary TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct TypeUsage /// Whether the binary type is fixed length or not /// The max length of the binary type ///A TypeUsage object describing a binary type with the given facet values public static TypeUsage CreateBinaryTypeUsage(PrimitiveType primitiveType, bool isFixedLength, int maxLength) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Binary) { throw EntityUtil.NotBinaryTypeForTypeUsage(); } ValidateMaxLength(maxLength); TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{MaxLength = maxLength, FixedLength = isFixedLength}); return typeUsage; } /// /// Factory method for creating a Binary TypeUsage object with the specified facets and /// unbounded MaxLength /// /// A PrimitiveType for which to construct the TypeUsage /// Whether the binary type is fixed length or not ///A TypeUsage object describing a binary type with the given facet values public static TypeUsage CreateBinaryTypeUsage(PrimitiveType primitiveType, bool isFixedLength) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Binary) { throw EntityUtil.NotBinaryTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{MaxLength = TypeUsage.DefaultMaxLengthFacetValue, FixedLength = isFixedLength}); return typeUsage; } /// /// Factory method for creating a DateTime TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct the TypeUsage /// Precision for seconds ///A TypeUsage object describing a DateTime type with the given facet values public static TypeUsage CreateDateTimeTypeUsage(PrimitiveType primitiveType, byte? precision) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.DateTime) { throw EntityUtil.NotDateTimeTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{Precision = precision}); return typeUsage; } /// /// Factory method for creating a DateTimeOffset TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct the TypeUsage /// Precision for seconds ///A TypeUsage object describing a DateTime type with the given facet values public static TypeUsage CreateDateTimeOffsetTypeUsage(PrimitiveType primitiveType, byte? precision) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.DateTimeOffset) { throw EntityUtil.NotDateTimeOffsetTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ Precision = precision }); return typeUsage; } /// /// Factory method for creating a Time TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct the TypeUsage /// Precision for seconds ///A TypeUsage object describing a Time type with the given facet values public static TypeUsage CreateTimeTypeUsage(PrimitiveType primitiveType, byte? precision) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Time) { throw EntityUtil.NotTimeTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ Precision = precision }); return typeUsage; } /// /// Factory method for creating a Decimal TypeUsage object with the specified facets /// /// A PrimitiveType for which to construct type usage /// The precision of the decimal type /// The scale of the decimal type ///A TypeUsage object describing a decimal type with the given facet values public static TypeUsage CreateDecimalTypeUsage(PrimitiveType primitiveType, byte precision, byte scale) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Decimal) { throw EntityUtil.NotDecimalTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{Precision = precision, Scale = scale }); return typeUsage; } /// /// Factory method for creating a Decimal TypeUsage object with unbounded precision and scale /// /// The PrimitiveType for which to construct type usage ///A TypeUsage object describing a decimal type with unbounded precision and scale public static TypeUsage CreateDecimalTypeUsage(PrimitiveType primitiveType) { EntityUtil.CheckArgumentNull(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Decimal) { throw EntityUtil.NotDecimalTypeForTypeUsage(); } TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues{ Precision = TypeUsage.DefaultPrecisionFacetValue, Scale = TypeUsage.DefaultScaleFacetValue }); return typeUsage; } #endregion #region Fields private TypeUsage _modelTypeUsage; private readonly EdmType _edmType; private ReadOnlyMetadataCollection _facets; private string _identity; /// /// Set of facets that should be included in identity for TypeUsage /// ///keep this sorted for binary searching private static readonly string[] s_identityFacets = new string[] { DbProviderManifest.DefaultValueFacetName, DbProviderManifest.FixedLengthFacetName, DbProviderManifest.MaxLengthFacetName, DbProviderManifest.NullableFacetName, DbProviderManifest.PrecisionFacetName, DbProviderManifest.ScaleFacetName, DbProviderManifest.UnicodeFacetName, }; internal static readonly EdmConstants.Unbounded DefaultMaxLengthFacetValue = EdmConstants.UnboundedValue; internal static readonly EdmConstants.Unbounded DefaultPrecisionFacetValue = EdmConstants.UnboundedValue; internal static readonly EdmConstants.Unbounded DefaultScaleFacetValue = EdmConstants.UnboundedValue; internal static readonly bool DefaultUnicodeFacetValue = true; internal static readonly bool DefaultFixedLengthFacetValue = false; internal static readonly byte? DefaultDateTimePrecisionFacetValue = null; #endregion #region Properties ////// Returns the kind of the type /// public override BuiltInTypeKind BuiltInTypeKind { get { return BuiltInTypeKind.TypeUsage; } } ////// Gets the type that this TypeUsage describes /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] [MetadataProperty(BuiltInTypeKind.EdmType, false)] public EdmType EdmType { get { return _edmType; } } ////// Gets the list of facets for the type in this TypeUsage /// [MetadataProperty(BuiltInTypeKind.Facet, true)] public ReadOnlyMetadataCollectionFacets { get { if (null == _facets) { MetadataCollection facets = new MetadataCollection (GetFacets()); // we never modify the collection so we can set it readonly from the start facets.SetReadOnly(); System.Threading.Interlocked.CompareExchange(ref _facets, facets.AsReadOnlyMetadataCollection(), null); } return _facets; } } #endregion #region Methods /// /// Returns a Model type usage for a provider type /// ///model (CSpace) type usage 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; } ////// check if "this" is a subtype of the specified TypeUsage /// /// The typeUsage to be checked ///true if this typeUsage is a subtype of the specified typeUsage public bool IsSubtypeOf(TypeUsage typeUsage) { if (EdmType == null || typeUsage == null) { return false; } return EdmType.IsSubtypeOf(typeUsage.EdmType); } private IEnumerableGetFacets() { foreach (FacetDescription facetDescription in _edmType.GetAssociatedFacetDescriptions()) { yield return facetDescription.DefaultValueFacet; } } internal override void SetReadOnly() { Debug.Fail("TypeUsage.SetReadOnly should not need to ever be called"); base.SetReadOnly(); } /// /// returns the identity of the type usage /// internal override String Identity { get { if (this.Facets.Count == 0) { return this.EdmType.Identity; } if (this._identity == null) { StringBuilder builder = new StringBuilder(128); BuildIdentity(builder); string identity = builder.ToString(); System.Threading.Interlocked.CompareExchange(ref _identity, identity, null); } return this._identity; } } private static IEnumerableGetDefaultFacetDescriptionsAndOverrideFacetValues(EdmType type, FacetValues values) { return OverrideFacetValues(type.GetAssociatedFacetDescriptions(), fd => fd, fd => fd.DefaultValueFacet, values); } private static IEnumerable OverrideFacetValues(IEnumerable facets, FacetValues values) { return OverrideFacetValues(facets, f => f.Description, f => f, values); } private static IEnumerable OverrideFacetValues (IEnumerable facetThings, Func getDescription, Func getFacet, FacetValues values) { // yield all the non custom values foreach (var thing in facetThings) { FacetDescription description = getDescription(thing); Facet facet; if (!description.IsConstant && values.TryGetFacet(description, out facet)) { yield return facet; } else { yield return getFacet(thing); } } } internal override void BuildIdentity(StringBuilder builder) { // if we've already cached the identity, simply append it if (null != _identity) { builder.Append(_identity); return; } builder.Append(this.EdmType.Identity); builder.Append("("); bool first = true; for (int j = 0; j < this.Facets.Count; j++) { Facet facet = this.Facets[j]; if (0 <= Array.BinarySearch(s_identityFacets, facet.Name, StringComparer.Ordinal)) { if (first) { first = false; } else { builder.Append(","); } builder.Append(facet.Name); builder.Append("="); // If the facet is present, add its value to the identity // We only include built-in system facets for the identity builder.Append(facet.Value ?? String.Empty); } } builder.Append(")"); } /// /// public override string ToString() { return EdmType.ToString(); } ////// EdmEquals override verifying the equivalence of all facets. Two facets are considered /// equal if they have the same name and the same value (Object.Equals) /// /// ///internal override bool EdmEquals(MetadataItem item) { // short-circuit if this and other are reference equivalent if (Object.ReferenceEquals(this, item)) { return true; } // check type of item if (null == item || BuiltInTypeKind.TypeUsage != item.BuiltInTypeKind) { return false; } TypeUsage other = (TypeUsage)item; // verify edm types are equivalent if (!this.EdmType.EdmEquals(other.EdmType)) { return false; } // if both usages have default facets, no need to compare if (null == this._facets && null == other._facets) { return true; } // initialize facets and compare if (this.Facets.Count != other.Facets.Count) { return false; } foreach (Facet thisFacet in this.Facets) { Facet otherFacet; if (!other.Facets.TryGetValue(thisFacet.Name, false, out otherFacet)) { // other type usage doesn't have the same facets as this type usage return false; } // check that the facet values are the same if (!Object.Equals(thisFacet.Value, otherFacet.Value)) { return false; } } return true; } private static void ValidateMaxLength(int maxLength) { if (maxLength <= 0) { throw EntityUtil.ArgumentOutOfRange(System.Data.Entity.Strings.InvalidMaxLengthSize, "maxLength"); } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ExpressionDumper.cs
- ReferenceTypeElement.cs
- ParallelTimeline.cs
- DEREncoding.cs
- RenderTargetBitmap.cs
- SerializationFieldInfo.cs
- MailHeaderInfo.cs
- RMEnrollmentPage3.cs
- SmtpAuthenticationManager.cs
- PageCatalogPart.cs
- FirstMatchCodeGroup.cs
- ToolStripScrollButton.cs
- FloaterParagraph.cs
- InvokeCompletedEventArgs.cs
- MembershipSection.cs
- QueryOptionExpression.cs
- WebResponse.cs
- InputScopeManager.cs
- DataGridViewRowPrePaintEventArgs.cs
- SupportingTokenChannel.cs
- PackageFilter.cs
- MultiAsyncResult.cs
- Assembly.cs
- ADMembershipProvider.cs
- ShaderEffect.cs
- adornercollection.cs
- Processor.cs
- SqlParameterCollection.cs
- ButtonChrome.cs
- RefreshPropertiesAttribute.cs
- StrongNameMembershipCondition.cs
- ResXResourceWriter.cs
- Int32Storage.cs
- DesignerUtility.cs
- LookupNode.cs
- MultiSelectRootGridEntry.cs
- SettingsAttributeDictionary.cs
- FullTextLine.cs
- RootBrowserWindow.cs
- Asn1IntegerConverter.cs
- DataGridViewImageColumn.cs
- UnsafeNativeMethods.cs
- EndOfStreamException.cs
- BaseProcessor.cs
- TableLayoutPanelCodeDomSerializer.cs
- ValidationErrorCollection.cs
- TypeInfo.cs
- NavigationService.cs
- WebBrowserUriTypeConverter.cs
- FrugalMap.cs
- HeaderUtility.cs
- StartFileNameEditor.cs
- FieldBuilder.cs
- FormViewDeleteEventArgs.cs
- AlternationConverter.cs
- CompilerGeneratedAttribute.cs
- UIntPtr.cs
- ZoneButton.cs
- WindowsAltTab.cs
- Opcode.cs
- SystemTcpStatistics.cs
- SamlSubjectStatement.cs
- AutoCompleteStringCollection.cs
- IOThreadScheduler.cs
- AppDomainGrammarProxy.cs
- Binding.cs
- MsmqHostedTransportConfiguration.cs
- DBNull.cs
- COM2DataTypeToManagedDataTypeConverter.cs
- ModifiableIteratorCollection.cs
- SendReply.cs
- StackBuilderSink.cs
- PropertyPath.cs
- AggregateNode.cs
- BinHexDecoder.cs
- ProtocolsSection.cs
- VectorAnimationBase.cs
- ReflectionUtil.cs
- DrawingGroupDrawingContext.cs
- FactoryGenerator.cs
- IsolatedStorageFileStream.cs
- BmpBitmapEncoder.cs
- basemetadatamappingvisitor.cs
- AdRotator.cs
- RectangleHotSpot.cs
- XmlLangPropertyAttribute.cs
- OptimalTextSource.cs
- StringHelper.cs
- MenuBase.cs
- X509Certificate.cs
- EditorZoneBase.cs
- GC.cs
- RoutingExtension.cs
- Internal.cs
- RemoveStoryboard.cs
- ContactManager.cs
- ValidationRule.cs
- EventLogEntryCollection.cs
- HostProtectionPermission.cs
- SafeArrayRankMismatchException.cs