Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Metadata / Edm / TypeUsage.cs / 1305376 / TypeUsage.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
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, IEnumerable facets)
: 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, IEnumerable facets)
{
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 ReadOnlyMetadataCollection Facets
{
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 IEnumerable GetFacets()
{
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 IEnumerable GetDefaultFacetDescriptionsAndOverrideFacetValues(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
- PerformanceCounterLib.cs
- StringConverter.cs
- Rfc2898DeriveBytes.cs
- ServiceHostFactory.cs
- ISFTagAndGuidCache.cs
- CompilerErrorCollection.cs
- Properties.cs
- RelatedPropertyManager.cs
- TreeNodeCollection.cs
- ClientCultureInfo.cs
- ItemCollection.cs
- SoapMessage.cs
- InstallerTypeAttribute.cs
- Metafile.cs
- NoneExcludedImageIndexConverter.cs
- ColorConvertedBitmap.cs
- XmlNode.cs
- XPathMessageFilterElementComparer.cs
- ObjectItemNoOpAssemblyLoader.cs
- KeyValuePair.cs
- BamlReader.cs
- XpsManager.cs
- CngUIPolicy.cs
- DataGridViewRowCancelEventArgs.cs
- EncryptedKey.cs
- ParallelTimeline.cs
- BitmapSizeOptions.cs
- DesignerAttribute.cs
- LocalizationComments.cs
- DoubleAnimationClockResource.cs
- UnmanagedMarshal.cs
- VScrollProperties.cs
- SqlBulkCopy.cs
- CalendarTable.cs
- MetadataException.cs
- WpfPayload.cs
- IntSecurity.cs
- BindingParameterCollection.cs
- SerialReceived.cs
- XmlEncoding.cs
- DataGridLinkButton.cs
- ClientBuildManager.cs
- SettingsContext.cs
- RsaSecurityTokenParameters.cs
- TextBox.cs
- ClientFormsAuthenticationCredentials.cs
- HtmlLink.cs
- GeometryGroup.cs
- SafeFileMappingHandle.cs
- templategroup.cs
- xmlNames.cs
- CodeNamespaceImport.cs
- BamlTreeUpdater.cs
- VisualBasicExpressionConverter.cs
- GreenMethods.cs
- InfoCardRSAPKCS1SignatureFormatter.cs
- ListSourceHelper.cs
- NullableFloatMinMaxAggregationOperator.cs
- XmlWrappingReader.cs
- EdmComplexPropertyAttribute.cs
- _SslState.cs
- HttpRequest.cs
- WindowsListViewItem.cs
- ListViewGroup.cs
- Debug.cs
- WebPartAuthorizationEventArgs.cs
- WebSysDescriptionAttribute.cs
- GregorianCalendar.cs
- BitSet.cs
- DataGridViewTextBoxEditingControl.cs
- ToolboxDataAttribute.cs
- RegexTree.cs
- DictionarySectionHandler.cs
- FlowPanelDesigner.cs
- InvalidFilterCriteriaException.cs
- CommandHelpers.cs
- PathGradientBrush.cs
- DictionaryBase.cs
- SrgsElement.cs
- TreeNodeBindingCollection.cs
- TraceUtility.cs
- TextEditorParagraphs.cs
- MarkupCompilePass2.cs
- Subset.cs
- KeyValueSerializer.cs
- TypeConstant.cs
- RoutingSection.cs
- SapiGrammar.cs
- DataGridViewButtonCell.cs
- ReferenceService.cs
- AppDomain.cs
- ProfileBuildProvider.cs
- DiffuseMaterial.cs
- WorkflowIdleBehavior.cs
- UTF8Encoding.cs
- CheckBoxBaseAdapter.cs
- ScriptResourceAttribute.cs
- TransformerInfoCollection.cs
- Int16Converter.cs
- WorkflowDefinitionDispenser.cs