Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Metadata / Edm / EntityType.cs / 1508357 / EntityType.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Security.Cryptography;
using System.Globalization;
namespace System.Data.Metadata.Edm
{
///
/// concrete Representation the Entity Type
///
public class EntityType : EntityTypeBase
{
#region Constructors
///
/// Initializes a new instance of Entity Type
///
/// name of the entity type
/// namespace of the entity type
/// version of the entity type
/// dataspace in which the EntityType belongs to
/// Thrown if either name, namespace or version arguments are null
internal EntityType(string name, string namespaceName, DataSpace dataSpace)
: base(name, namespaceName, dataSpace)
{
}
/// name of the entity type
/// namespace of the entity type
/// version of the entity type
/// dataspace in which the EntityType belongs to
/// members of the entity type [property and navigational property]
/// key members for the type
/// Thrown if either name, namespace or version arguments are null
internal EntityType(string name,
string namespaceName,
DataSpace dataSpace,
IEnumerable keyMemberNames,
IEnumerable members)
: base(name, namespaceName, dataSpace)
{
//--- first add the properties
if (null != members)
{
CheckAndAddMembers(members, this);
}
//--- second add the key members
if (null != keyMemberNames)
{
//Validation should make sure that base type of this type does not have keymembers when this type has keymembers.
CheckAndAddKeyMembers(keyMemberNames);
}
}
#endregion
#region Fields
/// cached dynamic method to construct a CLR instance
private RefType _referenceType;
private ReadOnlyMetadataCollection _properties;
private RowType _keyRow;
private Dictionary _memberSql;
private object _memberSqlLock = new object();
#endregion
#region Methods
///
/// Returns the kind of the type
///
public override BuiltInTypeKind BuiltInTypeKind { get { return BuiltInTypeKind.EntityType; } }
///
/// Validates a EdmMember object to determine if it can be added to this type's
/// Members collection. If this method returns without throwing, it is assumed
/// the member is valid.
///
/// The member to validate
/// Thrown if the member is not a EdmProperty
internal override void ValidateMemberForAdd(EdmMember member)
{
Debug.Assert(Helper.IsEdmProperty(member) || Helper.IsNavigationProperty(member),
"Only members of type Property may be added to Entity types.");
}
///
/// Get SQL description of a member of this entity type.
/// Requires: member must belong to this type
///
/// Member for which to retrieve SQL
/// Outputs SQL describing this member
/// Whether sql is cached for this member
internal bool TryGetMemberSql(EdmMember member, out string sql)
{
Debug.Assert(Members.Contains(member));
sql = null;
return null != _memberSql && _memberSql.TryGetValue(member, out sql);
}
///
/// Sets SQL describing a member of this entity type.
/// Requires: member must belong to this type
///
/// Member for which to set SQL
/// SQL describing this member
internal void SetMemberSql(EdmMember member, string sql)
{
Debug.Assert(Members.Contains(member));
// initialize dictionary on first use
lock (_memberSqlLock)
{
if (null == _memberSql)
{
_memberSql = new Dictionary();
}
_memberSql[member] = sql;
}
}
#endregion
#region Properties
///
/// Returns the list of Navigation Properties for this entity type
///
public ReadOnlyMetadataCollection NavigationProperties
{
get
{
return new FilteredReadOnlyMetadataCollection(
((ReadOnlyMetadataCollection)this.Members), Helper.IsNavigationProperty);
}
}
///
/// Returns just the properties from the collection
/// of members on this type
///
public ReadOnlyMetadataCollection Properties
{
get
{
Debug.Assert(IsReadOnly, "this is a wrapper around this.Members, don't call it during metadata loading, only call it after the metadata is set to readonly");
if (null == _properties)
{
Interlocked.CompareExchange(ref _properties,
new FilteredReadOnlyMetadataCollection(
this.Members, Helper.IsEdmProperty), null);
}
return _properties;
}
}
#endregion // Properties
///
/// Returns the Reference type pointing to this entity type
///
///
public RefType GetReferenceType()
{
if (_referenceType == null)
{
Interlocked.CompareExchange(ref _referenceType, new RefType(this), null);
}
return _referenceType;
}
internal RowType GetKeyRowType(MetadataWorkspace metadataWorkspace)
{
if (_keyRow == null)
{
List keyProperties = new List(KeyMembers.Count);
foreach (EdmMember keyMember in KeyMembers)
{
keyProperties.Add(new EdmProperty(keyMember.Name, Helper.GetModelTypeUsage(keyMember)));
}
Interlocked.CompareExchange(ref _keyRow, new RowType(keyProperties), null);
}
return _keyRow;
}
///
/// Attempts to get the property name for the ----oication between the two given end
/// names. Note that this property may not exist if a navigation property is defined
/// in one direction but not in the other.
///
/// the relationship for which a nav property is required
/// the 'from' end of the association
/// the 'to' end of the association
/// the property name, or null if none was found
/// true if a property was found, false otherwise
internal bool TryGetNavigationProperty(string relationshipType, string fromName, string toName, out NavigationProperty navigationProperty)
{
// This is a linear search but it's probably okay because the number of entries
// is generally small and this method is only called to generate code during lighweight
// code gen.
foreach (NavigationProperty navProperty in NavigationProperties)
{
if (navProperty.RelationshipType.FullName == relationshipType &&
navProperty.FromEndMember.Name == fromName &&
navProperty.ToEndMember.Name == toName)
{
navigationProperty = navProperty;
return true;
}
}
navigationProperty = null;
return false;
}
}
internal sealed class ClrEntityType : EntityType
{
/// cached CLR type handle, allowing the Type reference to be GC'd
private readonly System.RuntimeTypeHandle _type;
/// cached dynamic method to construct a CLR instance
private Delegate _constructor;
private readonly string _cspaceTypeName;
private readonly string _cspaceNamespaceName;
private string _hash;
///
/// Initializes a new instance of Complex Type with properties from the type.
///
/// The CLR type to construct from
internal ClrEntityType(Type type, string cspaceNamespaceName, string cspaceTypeName)
: base(EntityUtil.GenericCheckArgumentNull(type, "type").Name, type.Namespace ?? string.Empty,
DataSpace.OSpace)
{
System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(cspaceNamespaceName) &&
!String.IsNullOrEmpty(cspaceTypeName), "Mapping information must never be null");
_type = type.TypeHandle;
_cspaceNamespaceName = cspaceNamespaceName;
_cspaceTypeName = cspaceNamespaceName + "." + cspaceTypeName;
this.Abstract = type.IsAbstract;
}
/// cached dynamic method to construct a CLR instance
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Delegate Constructor
{
get { return _constructor; }
set
{
// It doesn't matter which delegate wins, but only one should be jitted
Interlocked.CompareExchange(ref _constructor, value, null);
}
}
///
///
internal override System.Type ClrType
{
get { return Type.GetTypeFromHandle(_type); }
}
internal string CSpaceTypeName { get { return _cspaceTypeName; } }
internal string CSpaceNamespaceName { get { return _cspaceNamespaceName; } }
///
/// Gets a collision resistent (SHA256) hash of the information used to build
/// a proxy for this type. This hash is very, very unlikely to be the same for two
/// proxies generated from the same CLR type but with different metadata, and is
/// guarenteed to be the same for proxies generated from the same metadata. This
/// means that when EntityType comparison fails because of metadata eviction,
/// the hash can be used to determine whether or not a proxy is of the correct type.
///
internal string HashedDescription
{
get
{
if (_hash == null)
{
Interlocked.CompareExchange(ref _hash, BuildEntityTypeHash(), null);
}
return _hash;
}
}
///
/// Creates an SHA256 hash of a description of all the metadata relevant to the creation of a proxy type
/// for this entity type.
///
private string BuildEntityTypeHash()
{
var hash = System.Data.Common.Utils.MetadataHelper.CreateSHA256HashAlgorithm()
.ComputeHash(Encoding.ASCII.GetBytes(BuildEntityTypeDescription()));
// convert num bytes to num hex digits
var builder = new StringBuilder(hash.Length * 2);
foreach (byte bite in hash)
{
builder.Append(bite.ToString("X2", CultureInfo.InvariantCulture));
}
return builder.ToString();
}
///
/// Creates a description of all the metadata relevant to the creation of a proxy type
/// for this entity type.
///
private string BuildEntityTypeDescription()
{
var builder = new StringBuilder(512);
Debug.Assert(ClrType != null, "Expecting non-null CLRType of o-space EntityType.");
builder.Append("CLR:").Append(ClrType.FullName);
builder.Append("Conceptual:").Append(CSpaceTypeName);
var navProps = new SortedSet();
foreach (var navProperty in NavigationProperties)
{
navProps.Add(navProperty.Name + "*" +
navProperty.FromEndMember.Name + "*" +
navProperty.FromEndMember.RelationshipMultiplicity + "*" +
navProperty.ToEndMember.Name + "*" +
navProperty.ToEndMember.RelationshipMultiplicity + "*");
}
builder.Append("NavProps:");
foreach (var navProp in navProps)
{
builder.Append(navProp);
}
var keys = new SortedSet();
foreach (var member in KeyMemberNames)
{
keys.Add(member);
}
builder.Append("Keys:");
foreach (var key in keys)
{
builder.Append(key + "*");
}
var scalars = new SortedSet();
foreach (var member in Members)
{
if (!keys.Contains(member.Name))
{
scalars.Add(member.Name + "*");
}
}
builder.Append("Scalars:");
foreach (var scalar in scalars)
{
builder.Append(scalar + "*");
}
return builder.ToString();
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Security.Cryptography;
using System.Globalization;
namespace System.Data.Metadata.Edm
{
///
/// concrete Representation the Entity Type
///
public class EntityType : EntityTypeBase
{
#region Constructors
///
/// Initializes a new instance of Entity Type
///
/// name of the entity type
/// namespace of the entity type
/// version of the entity type
/// dataspace in which the EntityType belongs to
/// Thrown if either name, namespace or version arguments are null
internal EntityType(string name, string namespaceName, DataSpace dataSpace)
: base(name, namespaceName, dataSpace)
{
}
/// name of the entity type
/// namespace of the entity type
/// version of the entity type
/// dataspace in which the EntityType belongs to
/// members of the entity type [property and navigational property]
/// key members for the type
/// Thrown if either name, namespace or version arguments are null
internal EntityType(string name,
string namespaceName,
DataSpace dataSpace,
IEnumerable keyMemberNames,
IEnumerable members)
: base(name, namespaceName, dataSpace)
{
//--- first add the properties
if (null != members)
{
CheckAndAddMembers(members, this);
}
//--- second add the key members
if (null != keyMemberNames)
{
//Validation should make sure that base type of this type does not have keymembers when this type has keymembers.
CheckAndAddKeyMembers(keyMemberNames);
}
}
#endregion
#region Fields
/// cached dynamic method to construct a CLR instance
private RefType _referenceType;
private ReadOnlyMetadataCollection _properties;
private RowType _keyRow;
private Dictionary _memberSql;
private object _memberSqlLock = new object();
#endregion
#region Methods
///
/// Returns the kind of the type
///
public override BuiltInTypeKind BuiltInTypeKind { get { return BuiltInTypeKind.EntityType; } }
///
/// Validates a EdmMember object to determine if it can be added to this type's
/// Members collection. If this method returns without throwing, it is assumed
/// the member is valid.
///
/// The member to validate
/// Thrown if the member is not a EdmProperty
internal override void ValidateMemberForAdd(EdmMember member)
{
Debug.Assert(Helper.IsEdmProperty(member) || Helper.IsNavigationProperty(member),
"Only members of type Property may be added to Entity types.");
}
///
/// Get SQL description of a member of this entity type.
/// Requires: member must belong to this type
///
/// Member for which to retrieve SQL
/// Outputs SQL describing this member
/// Whether sql is cached for this member
internal bool TryGetMemberSql(EdmMember member, out string sql)
{
Debug.Assert(Members.Contains(member));
sql = null;
return null != _memberSql && _memberSql.TryGetValue(member, out sql);
}
///
/// Sets SQL describing a member of this entity type.
/// Requires: member must belong to this type
///
/// Member for which to set SQL
/// SQL describing this member
internal void SetMemberSql(EdmMember member, string sql)
{
Debug.Assert(Members.Contains(member));
// initialize dictionary on first use
lock (_memberSqlLock)
{
if (null == _memberSql)
{
_memberSql = new Dictionary();
}
_memberSql[member] = sql;
}
}
#endregion
#region Properties
///
/// Returns the list of Navigation Properties for this entity type
///
public ReadOnlyMetadataCollection NavigationProperties
{
get
{
return new FilteredReadOnlyMetadataCollection(
((ReadOnlyMetadataCollection)this.Members), Helper.IsNavigationProperty);
}
}
///
/// Returns just the properties from the collection
/// of members on this type
///
public ReadOnlyMetadataCollection Properties
{
get
{
Debug.Assert(IsReadOnly, "this is a wrapper around this.Members, don't call it during metadata loading, only call it after the metadata is set to readonly");
if (null == _properties)
{
Interlocked.CompareExchange(ref _properties,
new FilteredReadOnlyMetadataCollection(
this.Members, Helper.IsEdmProperty), null);
}
return _properties;
}
}
#endregion // Properties
///
/// Returns the Reference type pointing to this entity type
///
///
public RefType GetReferenceType()
{
if (_referenceType == null)
{
Interlocked.CompareExchange(ref _referenceType, new RefType(this), null);
}
return _referenceType;
}
internal RowType GetKeyRowType(MetadataWorkspace metadataWorkspace)
{
if (_keyRow == null)
{
List keyProperties = new List(KeyMembers.Count);
foreach (EdmMember keyMember in KeyMembers)
{
keyProperties.Add(new EdmProperty(keyMember.Name, Helper.GetModelTypeUsage(keyMember)));
}
Interlocked.CompareExchange(ref _keyRow, new RowType(keyProperties), null);
}
return _keyRow;
}
///
/// Attempts to get the property name for the ----oication between the two given end
/// names. Note that this property may not exist if a navigation property is defined
/// in one direction but not in the other.
///
/// the relationship for which a nav property is required
/// the 'from' end of the association
/// the 'to' end of the association
/// the property name, or null if none was found
/// true if a property was found, false otherwise
internal bool TryGetNavigationProperty(string relationshipType, string fromName, string toName, out NavigationProperty navigationProperty)
{
// This is a linear search but it's probably okay because the number of entries
// is generally small and this method is only called to generate code during lighweight
// code gen.
foreach (NavigationProperty navProperty in NavigationProperties)
{
if (navProperty.RelationshipType.FullName == relationshipType &&
navProperty.FromEndMember.Name == fromName &&
navProperty.ToEndMember.Name == toName)
{
navigationProperty = navProperty;
return true;
}
}
navigationProperty = null;
return false;
}
}
internal sealed class ClrEntityType : EntityType
{
/// cached CLR type handle, allowing the Type reference to be GC'd
private readonly System.RuntimeTypeHandle _type;
/// cached dynamic method to construct a CLR instance
private Delegate _constructor;
private readonly string _cspaceTypeName;
private readonly string _cspaceNamespaceName;
private string _hash;
///
/// Initializes a new instance of Complex Type with properties from the type.
///
/// The CLR type to construct from
internal ClrEntityType(Type type, string cspaceNamespaceName, string cspaceTypeName)
: base(EntityUtil.GenericCheckArgumentNull(type, "type").Name, type.Namespace ?? string.Empty,
DataSpace.OSpace)
{
System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(cspaceNamespaceName) &&
!String.IsNullOrEmpty(cspaceTypeName), "Mapping information must never be null");
_type = type.TypeHandle;
_cspaceNamespaceName = cspaceNamespaceName;
_cspaceTypeName = cspaceNamespaceName + "." + cspaceTypeName;
this.Abstract = type.IsAbstract;
}
/// cached dynamic method to construct a CLR instance
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Delegate Constructor
{
get { return _constructor; }
set
{
// It doesn't matter which delegate wins, but only one should be jitted
Interlocked.CompareExchange(ref _constructor, value, null);
}
}
///
///
internal override System.Type ClrType
{
get { return Type.GetTypeFromHandle(_type); }
}
internal string CSpaceTypeName { get { return _cspaceTypeName; } }
internal string CSpaceNamespaceName { get { return _cspaceNamespaceName; } }
///
/// Gets a collision resistent (SHA256) hash of the information used to build
/// a proxy for this type. This hash is very, very unlikely to be the same for two
/// proxies generated from the same CLR type but with different metadata, and is
/// guarenteed to be the same for proxies generated from the same metadata. This
/// means that when EntityType comparison fails because of metadata eviction,
/// the hash can be used to determine whether or not a proxy is of the correct type.
///
internal string HashedDescription
{
get
{
if (_hash == null)
{
Interlocked.CompareExchange(ref _hash, BuildEntityTypeHash(), null);
}
return _hash;
}
}
///
/// Creates an SHA256 hash of a description of all the metadata relevant to the creation of a proxy type
/// for this entity type.
///
private string BuildEntityTypeHash()
{
var hash = System.Data.Common.Utils.MetadataHelper.CreateSHA256HashAlgorithm()
.ComputeHash(Encoding.ASCII.GetBytes(BuildEntityTypeDescription()));
// convert num bytes to num hex digits
var builder = new StringBuilder(hash.Length * 2);
foreach (byte bite in hash)
{
builder.Append(bite.ToString("X2", CultureInfo.InvariantCulture));
}
return builder.ToString();
}
///
/// Creates a description of all the metadata relevant to the creation of a proxy type
/// for this entity type.
///
private string BuildEntityTypeDescription()
{
var builder = new StringBuilder(512);
Debug.Assert(ClrType != null, "Expecting non-null CLRType of o-space EntityType.");
builder.Append("CLR:").Append(ClrType.FullName);
builder.Append("Conceptual:").Append(CSpaceTypeName);
var navProps = new SortedSet();
foreach (var navProperty in NavigationProperties)
{
navProps.Add(navProperty.Name + "*" +
navProperty.FromEndMember.Name + "*" +
navProperty.FromEndMember.RelationshipMultiplicity + "*" +
navProperty.ToEndMember.Name + "*" +
navProperty.ToEndMember.RelationshipMultiplicity + "*");
}
builder.Append("NavProps:");
foreach (var navProp in navProps)
{
builder.Append(navProp);
}
var keys = new SortedSet();
foreach (var member in KeyMemberNames)
{
keys.Add(member);
}
builder.Append("Keys:");
foreach (var key in keys)
{
builder.Append(key + "*");
}
var scalars = new SortedSet();
foreach (var member in Members)
{
if (!keys.Contains(member.Name))
{
scalars.Add(member.Name + "*");
}
}
builder.Append("Scalars:");
foreach (var scalar in scalars)
{
builder.Append(scalar + "*");
}
return builder.ToString();
}
}
}
// 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
- FontUnit.cs
- SqlConnectionPoolGroupProviderInfo.cs
- ToolStripHighContrastRenderer.cs
- TextTrailingCharacterEllipsis.cs
- AdornerDecorator.cs
- RedistVersionInfo.cs
- SqlOuterApplyReducer.cs
- Track.cs
- __Filters.cs
- HostAdapter.cs
- ContainerFilterService.cs
- ScaleTransform.cs
- Group.cs
- ResourceContainerWrapper.cs
- TypeExtensions.cs
- XPathDocumentBuilder.cs
- ObjectSecurityT.cs
- DataList.cs
- BatchParser.cs
- BookmarkTable.cs
- DataGridViewLinkCell.cs
- RetrieveVirtualItemEventArgs.cs
- Nullable.cs
- WSSecurityOneDotZeroSendSecurityHeader.cs
- XmlJsonReader.cs
- DispatcherHookEventArgs.cs
- IHttpResponseInternal.cs
- DesignTimeXamlWriter.cs
- ModuleConfigurationInfo.cs
- DynamicMetaObject.cs
- PartitionedStreamMerger.cs
- ExpressionBuilder.cs
- UInt64.cs
- MetadataHelper.cs
- LinqDataSourceContextEventArgs.cs
- HtmlTableRow.cs
- IDispatchConstantAttribute.cs
- QueryStringParameter.cs
- EventDescriptor.cs
- AutomationTextAttribute.cs
- UpdateManifestForBrowserApplication.cs
- ViewRendering.cs
- SmiXetterAccessMap.cs
- InfoCard.cs
- WebServiceParameterData.cs
- LifetimeServices.cs
- IisTraceListener.cs
- Transactions.cs
- ImpersonationContext.cs
- MailWebEventProvider.cs
- TextBox.cs
- ScrollProviderWrapper.cs
- RtfToken.cs
- ByteStream.cs
- StagingAreaInputItem.cs
- ToolboxDataAttribute.cs
- WebException.cs
- SQLCharsStorage.cs
- XmlNode.cs
- WebPartDisplayModeCancelEventArgs.cs
- DataGridViewCellToolTipTextNeededEventArgs.cs
- TextSerializer.cs
- EnumerableValidator.cs
- DataGridViewRowsAddedEventArgs.cs
- HealthMonitoringSection.cs
- Label.cs
- _CookieModule.cs
- XmlSchemaAnnotated.cs
- DataService.cs
- SqlClientWrapperSmiStreamChars.cs
- MessageBox.cs
- VirtualizingStackPanel.cs
- PDBReader.cs
- LinkLabel.cs
- WindowsListViewGroupHelper.cs
- MaskInputRejectedEventArgs.cs
- EventLogger.cs
- ConsumerConnectionPointCollection.cs
- TargetControlTypeCache.cs
- SharedStream.cs
- ImageSourceConverter.cs
- ThreadAbortException.cs
- DataMisalignedException.cs
- ParenExpr.cs
- EpmSourcePathSegment.cs
- ClickablePoint.cs
- Object.cs
- AssemblySettingAttributes.cs
- SignatureResourcePool.cs
- SqlCachedBuffer.cs
- MemberDomainMap.cs
- TextPenaltyModule.cs
- TablePattern.cs
- MemberAccessException.cs
- QueryAccessibilityHelpEvent.cs
- keycontainerpermission.cs
- PreservationFileReader.cs
- OrderingInfo.cs
- ServiceModelEnumValidatorAttribute.cs
- RuleSetReference.cs