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
- CustomCredentialPolicy.cs
- DataGrid.cs
- ViewLoader.cs
- CodeTypeMemberCollection.cs
- KeyValueInternalCollection.cs
- PersonalizableTypeEntry.cs
- ConfigurationStrings.cs
- WorkerProcess.cs
- RoleManagerEventArgs.cs
- CellParaClient.cs
- CodeTypeDelegate.cs
- DocumentXPathNavigator.cs
- EncoderParameter.cs
- CompleteWizardStep.cs
- PrimitiveXmlSerializers.cs
- DrawingAttributes.cs
- HttpStreams.cs
- SizeFConverter.cs
- SqlNodeTypeOperators.cs
- ConfigurationStrings.cs
- DataAdapter.cs
- PropertyCollection.cs
- X509ThumbprintKeyIdentifierClause.cs
- AutomationProperties.cs
- Decorator.cs
- SchemaImporterExtension.cs
- __Error.cs
- ContentValidator.cs
- SrgsSemanticInterpretationTag.cs
- RenderCapability.cs
- SortDescription.cs
- WindowsAltTab.cs
- XPathNodeList.cs
- RealizationDrawingContextWalker.cs
- MenuItemCollection.cs
- XsltOutput.cs
- RenderDataDrawingContext.cs
- ViewValidator.cs
- SymbolType.cs
- TextBoxBase.cs
- NumberFormatInfo.cs
- DnsPermission.cs
- BindingOperations.cs
- CustomTypeDescriptor.cs
- ConfigsHelper.cs
- RuleCache.cs
- BaseCollection.cs
- EntityDataSourceChangedEventArgs.cs
- EventLogPermission.cs
- Activity.cs
- PropVariant.cs
- SystemDropShadowChrome.cs
- EmissiveMaterial.cs
- TextElement.cs
- QilName.cs
- BufferedStream.cs
- MembershipValidatePasswordEventArgs.cs
- InstanceHandle.cs
- DayRenderEvent.cs
- TableLayoutPanel.cs
- StatusStrip.cs
- BaseCodePageEncoding.cs
- MaskedTextProvider.cs
- TraceSection.cs
- Size.cs
- FixedHighlight.cs
- TextCompositionManager.cs
- OciLobLocator.cs
- Wizard.cs
- RootProfilePropertySettingsCollection.cs
- EdmProperty.cs
- SiteMapSection.cs
- ListViewGroup.cs
- FigureParaClient.cs
- CqlParserHelpers.cs
- Viewport3DAutomationPeer.cs
- WorkflowMessageEventArgs.cs
- OleTxTransaction.cs
- Win32MouseDevice.cs
- TextDecorationCollection.cs
- SafeTimerHandle.cs
- sqlinternaltransaction.cs
- TransportChannelFactory.cs
- FileDialog_Vista_Interop.cs
- TextFormatter.cs
- _NTAuthentication.cs
- FileVersionInfo.cs
- WebBrowserNavigatedEventHandler.cs
- AsyncWaitHandle.cs
- DispatchChannelSink.cs
- ScrollContentPresenter.cs
- XpsFixedPageReaderWriter.cs
- ObjectAnimationBase.cs
- PasswordRecoveryDesigner.cs
- ListControl.cs
- RijndaelManaged.cs
- CodeSpit.cs
- PersianCalendar.cs
- TrackingProfileDeserializationException.cs
- DetailsViewDeletedEventArgs.cs