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
- Pair.cs
- webbrowsersite.cs
- WindowPattern.cs
- TypeValidationEventArgs.cs
- TreeNodeStyleCollectionEditor.cs
- CroppedBitmap.cs
- UnsafeNativeMethods.cs
- DataGridRelationshipRow.cs
- SqlBulkCopyColumnMapping.cs
- BindableTemplateBuilder.cs
- HtmlGenericControl.cs
- ObjectCacheSettings.cs
- SpecialNameAttribute.cs
- CssStyleCollection.cs
- FieldNameLookup.cs
- PackWebRequest.cs
- ComponentResourceManager.cs
- FileDialogCustomPlacesCollection.cs
- InProcStateClientManager.cs
- SiteMapHierarchicalDataSourceView.cs
- ProgressChangedEventArgs.cs
- DivideByZeroException.cs
- VersionedStreamOwner.cs
- LabelEditEvent.cs
- CfgRule.cs
- NoClickablePointException.cs
- LogicalMethodInfo.cs
- SrgsOneOf.cs
- panel.cs
- SamlAuthenticationClaimResource.cs
- ListBase.cs
- SqlRetyper.cs
- StreamWriter.cs
- XmlCharCheckingReader.cs
- Light.cs
- XslException.cs
- ContextStaticAttribute.cs
- StyleModeStack.cs
- BinaryObjectReader.cs
- SpecularMaterial.cs
- ToolStripItemBehavior.cs
- VideoDrawing.cs
- DataGridViewCellCancelEventArgs.cs
- PackagePart.cs
- ToolStripCollectionEditor.cs
- ProjectionNode.cs
- CustomWebEventKey.cs
- WebControl.cs
- XmlBoundElement.cs
- ConfigurationStrings.cs
- RectangleHotSpot.cs
- Missing.cs
- ParallelDesigner.cs
- HttpException.cs
- ItemAutomationPeer.cs
- SplitterPanel.cs
- DesignerUtility.cs
- Margins.cs
- RotateTransform.cs
- SelectorItemAutomationPeer.cs
- CellParaClient.cs
- LineServicesRun.cs
- GenerateScriptTypeAttribute.cs
- EmptyEnumerable.cs
- ClockController.cs
- EntityDataSourceValidationException.cs
- UserMapPath.cs
- SessionParameter.cs
- DataProviderNameConverter.cs
- LayoutEvent.cs
- ColorComboBox.cs
- ExceptionHandler.cs
- SmtpMail.cs
- DataObjectSettingDataEventArgs.cs
- CompilerParameters.cs
- SQLMembershipProvider.cs
- Win32NamedPipes.cs
- DataGridColumnHeader.cs
- BatchWriter.cs
- ZipIOLocalFileDataDescriptor.cs
- CodeAttributeDeclaration.cs
- TransactionManager.cs
- ShutDownListener.cs
- DataGridViewImageColumn.cs
- XmlNodeWriter.cs
- SamlConditions.cs
- TextEffect.cs
- CodeStatementCollection.cs
- DataGridViewSortCompareEventArgs.cs
- OuterGlowBitmapEffect.cs
- KeyedHashAlgorithm.cs
- UnsafeNativeMethods.cs
- TextEffectResolver.cs
- AssemblyAssociatedContentFileAttribute.cs
- ResXResourceWriter.cs
- CodeIterationStatement.cs
- DependsOnAttribute.cs
- PropertySegmentSerializationProvider.cs
- CodeTypeReferenceSerializer.cs
- QilTypeChecker.cs