Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlSerializerFactory.cs
- XmlSerializationGeneratedCode.cs
- LineBreak.cs
- Margins.cs
- SqlProviderManifest.cs
- BitmapSourceSafeMILHandle.cs
- Monitor.cs
- ProcessStartInfo.cs
- SqlVersion.cs
- XpsPartBase.cs
- ResourceManager.cs
- ScriptDescriptor.cs
- SafeHGlobalHandleCritical.cs
- ObjectParameter.cs
- PathGeometry.cs
- Timer.cs
- ThreadExceptionEvent.cs
- ChangePassword.cs
- Trace.cs
- _LocalDataStoreMgr.cs
- TextEditorLists.cs
- RSAOAEPKeyExchangeDeformatter.cs
- UICuesEvent.cs
- SolidColorBrush.cs
- _IPv6Address.cs
- GenericQueueSurrogate.cs
- DataGridViewComboBoxEditingControl.cs
- SearchForVirtualItemEventArgs.cs
- ToolboxItemCollection.cs
- PathGeometry.cs
- ViewKeyConstraint.cs
- peersecurityelement.cs
- DataGridViewUtilities.cs
- StylusButtonEventArgs.cs
- ReadOnlyNameValueCollection.cs
- FunctionCommandText.cs
- PackagePartCollection.cs
- DetailsViewRow.cs
- Window.cs
- ImageSourceConverter.cs
- BamlRecordReader.cs
- XDRSchema.cs
- SizeAnimationClockResource.cs
- IgnoreDeviceFilterElementCollection.cs
- LateBoundBitmapDecoder.cs
- DesignerContextDescriptor.cs
- DateTime.cs
- Encoder.cs
- ConstrainedGroup.cs
- WorkflowMessageEventHandler.cs
- SqlGatherConsumedAliases.cs
- Expressions.cs
- ReplyAdapterChannelListener.cs
- IpcPort.cs
- ReadOnlyDataSourceView.cs
- SelfIssuedAuthAsymmetricKey.cs
- TabOrder.cs
- ProxyAttribute.cs
- Funcletizer.cs
- HtmlTableCell.cs
- XmlText.cs
- RangeEnumerable.cs
- TokenizerHelper.cs
- DataSourceCache.cs
- HtmlSelect.cs
- FileChangesMonitor.cs
- ControlBindingsConverter.cs
- ListViewTableRow.cs
- TextViewBase.cs
- WebScriptMetadataMessageEncoderFactory.cs
- HijriCalendar.cs
- Win32.cs
- TextBoxBase.cs
- ProcessRequestArgs.cs
- TextTabProperties.cs
- _HeaderInfoTable.cs
- PageSettings.cs
- MSHTMLHost.cs
- Visual3D.cs
- TabControlAutomationPeer.cs
- DirectoryNotFoundException.cs
- Vector3DValueSerializer.cs
- ValueTypePropertyReference.cs
- FastEncoder.cs
- SizeConverter.cs
- mda.cs
- InfoCardRSACryptoProvider.cs
- MatrixKeyFrameCollection.cs
- embossbitmapeffect.cs
- xmlsaver.cs
- CodePageEncoding.cs
- WindowProviderWrapper.cs
- SequenceDesignerAccessibleObject.cs
- DataService.cs
- WebPartConnectionsDisconnectVerb.cs
- WorkflowView.cs
- PersistenceContextEnlistment.cs
- DPCustomTypeDescriptor.cs
- OleDbWrapper.cs
- WebBrowserNavigatedEventHandler.cs