Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / EntityDescriptor.cs / 1305376 / EntityDescriptor.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// represents the object and state // //--------------------------------------------------------------------- namespace System.Data.Services.Client { using System.Diagnostics; using System.Globalization; ////// represents the cached entity /// [DebuggerDisplay("State = {state}, Uri = {editLink}, Element = {entity.GetType().ToString()}")] public sealed class EntityDescriptor : Descriptor { #region Fields ///uri to identitfy the entity ///<atom:id>identity</id> private String identity; ///entity private object entity; ///entity tag private string etag; ///ETag for the media resource if this is a media link entry. private string streamETag; ///The parent resource that this resource is linked to. private EntityDescriptor parentDescriptor; ///Parent resource property to which this node is linked private string parentProperty; ///String storing the server type related to this entity private string serverTypeName; ///uri to query the entity ///<atom:link rel="self" href="queryLink" /> private Uri selfLink; ///uri to edit the entity. In case of deep add, this can also refer to the navigation property name. ///<atom:link rel="edit" href="editLink" /> private Uri editLink; ///In case of Media Link Entry, this is the link to the Media Resource (content). /// Otherwise this is null. ///<atom:content src="contentLink" /> private Uri readStreamLink; ///In case of Media Link Entry, this is the edit-media link value. /// Otherwise this is null. ///<atom:link rel="edit-media" href="editMediaLink" /> private Uri editMediaLink; ///The save stream associated with this MLE. ///When set the entity is treated as MLE and will participate in SaveChanges /// (even if its state is Unmodified). If the state of the entity is Added first /// the MR will be POSTed using this stream as the content then the entity will be PUT/MERGE as MLE. /// If the state of the entity is Unmodified only the MR will be PUT using this stream as the content. /// If the state of the entity is Changed first the MR will be PUT using this stream as the content /// and then the entity will be PUT/MERGE as MLE. /// If the state of the entity is Deleted this stream is not going to be used. /// /// SaveChanges will call CloseSaveStream on this object after it returns regardless of it succeeding or not. /// SaveChanges will call the method even if it didn't get to process the entity (failed sooner). /// The CloseSaveStream method will close the stream if it's owned by the object and will set this field to null. private DataServiceContext.DataServiceSaveStream saveStream; ///Set to true if the entity represented by this box is an MLE entity. ///Since in some cases we don't know upfront if the entity is MLE or not, we use this boolean to remember the fact /// once we learn it. For example for POCO entities the entity becomes MLE only once a SetSaveStream is called on it. /// Also once the entity has become MLE it can't change that while we're tracking it (since it will be MLE on the server as well). /// That's why we only set thhis to true and never back to false. private bool mediaLinkEntry; ////// Describes whether the SaveStream is for Insert or Update. /// The value NoStream is for both non-MLEs and MLEs with unmodified stream. /// private StreamStates streamState; ////// The entity set name to be used to insert the entity. /// private string entitySetName; #endregion ////// Constructor /// /// resource Uri /// query link of entity /// edit link of entity /// entity /// parent entity /// Parent entity property to which this entity is linked /// name of the entity set to which the entity belongs. /// etag /// entity state internal EntityDescriptor(String identity, Uri selfLink, Uri editLink, object entity, EntityDescriptor parentEntity, string parentProperty, string entitySetName, string etag, EntityStates state) : base(state) { Debug.Assert(entity != null, "entity is null"); Debug.Assert((parentEntity == null && parentProperty == null) || (parentEntity != null && parentProperty != null), "When parentEntity is specified, must also specify parentProperyName"); #if DEBUG if (state == EntityStates.Added) { Debug.Assert(identity == null && selfLink == null && editLink == null && etag == null, "For objects in added state, identity, self-link, edit-link and etag must be null"); Debug.Assert((!String.IsNullOrEmpty(entitySetName) && parentEntity == null && String.IsNullOrEmpty(parentProperty)) || (String.IsNullOrEmpty(entitySetName) && parentEntity != null && !String.IsNullOrEmpty(parentProperty)), "For entities in added state, entity set name or the insert path must be specified"); } else { // For some read-only service, editlink can be null. They can only specify self-links. Debug.Assert(identity != null, "For objects in non-added state, identity must never be null"); Debug.Assert(String.IsNullOrEmpty(entitySetName) && String.IsNullOrEmpty(parentProperty) && parentEntity == null, "For non-added entities, the entity set name and the insert path must be null"); } #endif // Identity can be null if object is just added (AddObject) this.identity = identity; this.selfLink = selfLink; this.editLink = editLink; this.parentDescriptor = parentEntity; this.parentProperty = parentProperty; this.entity = entity; this.etag = etag; this.entitySetName = entitySetName; } #region Properties ///entity uri identity public String Identity { get { return this.identity; } internal set { Util.CheckArgumentNotEmpty(value, "Identity"); this.identity = value; this.parentDescriptor = null; this.parentProperty = null; this.entitySetName = null; } } ///uri to query entity public Uri SelfLink { get { return this.selfLink; } internal set { this.selfLink = value; } } ///uri to edit entity public Uri EditLink { get { return this.editLink; } internal set { this.editLink = value; } } ////// If the entity for the box is an MLE this property stores the content source URI of the MLE. /// That is, it stores the read URI for the associated MR. /// Setting it to non-null marks the entity as MLE. /// public Uri ReadStreamUri { get { return this.readStreamLink; } internal set { this.readStreamLink = value; if (value != null) { this.mediaLinkEntry = true; } } } ////// If the entity for the box is an MLE this property stores the edit-media link URI. /// That is, it stores the URI to send PUTs for the associated MR. /// Setting it to non-null marks the entity as MLE. /// public Uri EditStreamUri { get { return this.editMediaLink; } internal set { this.editMediaLink = value; if (value != null) { this.mediaLinkEntry = true; } } } ///entity public object Entity { get { return this.entity; } } ///etag public string ETag { get { return this.etag; } internal set { this.etag = value; } } ///ETag for the media resource if this is a media link entry. public string StreamETag { get { return this.streamETag; } internal set { Debug.Assert(this.mediaLinkEntry == true, "this.mediaLinkEntry == true"); this.streamETag = value; } } ///Parent entity descriptor. ///This is only set for entities added through AddRelateObject call public EntityDescriptor ParentForInsert { get { return this.parentDescriptor; } } ///Parent entity property to which this entity is linked public string ParentPropertyForInsert { get { return this.parentProperty; } } ///Server type string public String ServerTypeName { get { return this.serverTypeName; } internal set { this.serverTypeName = value; } } #endregion #region Internal Properties // These properties are used internally for state tracking ///Parent entity internal object ParentEntity { get { return this.parentDescriptor != null ? this.parentDescriptor.entity : null; } } ///this is a entity internal override bool IsResource { get { return true; } } ////// Returns true if the resource was inserted via its parent. E.g. POST customer(0)/Orders /// internal bool IsDeepInsert { get { return this.parentDescriptor != null; } } ////// The stream which contains the new content for the MR associated with this MLE. /// This stream is used during SaveChanges to POST/PUT the MR. /// Setting it to non-null marks the entity as MLE. /// internal DataServiceContext.DataServiceSaveStream SaveStream { get { return this.saveStream; } set { this.saveStream = value; if (value != null) { this.mediaLinkEntry = true; } } } ////// Describes whether the SaveStream is for Insert or Update. /// The value NoStream is for both non-MLEs and MLEs with unmodified stream. /// internal StreamStates StreamState { get { return this.streamState; } set { this.streamState = value; Debug.Assert(this.streamState == StreamStates.NoStream || this.mediaLinkEntry, "this.streamState == StreamStates.NoStream || this.mediaLinkEntry"); Debug.Assert( (this.saveStream == null && this.streamState == StreamStates.NoStream) || (this.saveStream != null && this.streamState != StreamStates.NoStream), "(this.saveStream == null && this.streamState == StreamStates.NoStream) || (this.saveStream != null && this.streamState != StreamStates.NoStream)"); } } ////// Returns true if we know that the entity is MLE. Note that this does not include the information /// from the entity type. So if the entity was attributed with HasStream for example /// this boolean might not be aware of it. /// internal bool IsMediaLinkEntry { get { return this.mediaLinkEntry; } } ////// Returns true if the entry has been modified (and thus should participate in SaveChanges). /// internal override bool IsModified { get { if (base.IsModified) { return true; } else { // If the entity is not modified but it does have a save stream associated with it // it means that the MR for the MLE should be updated and thus we need to consider // the entity as modified (so that it shows up during SaveChanges) return this.saveStream != null; } } } #endregion #region Internal Methods ///uri to edit the entity /// baseUriWithSlash /// whether to return the query link or edit link ///absolute uri which can be used to edit the entity internal Uri GetResourceUri(Uri baseUriWithSlash, bool queryLink) { // If the entity was inserted using the AddRelatedObject API if (this.parentDescriptor != null) { // This is the batch scenario, where the entity might not have been saved yet, and there is another operation // (for e.g. PUT $1/links/BestFriend or something). Hence we need to generate a Uri with the changeorder number. if (this.parentDescriptor.Identity == null) { return Util.CreateUri( Util.CreateUri(baseUriWithSlash, new Uri("$" + this.parentDescriptor.ChangeOrder.ToString(CultureInfo.InvariantCulture), UriKind.Relative)), Util.CreateUri(this.parentProperty, UriKind.Relative)); } else { return Util.CreateUri(Util.CreateUri(baseUriWithSlash, this.parentDescriptor.GetLink(queryLink)), this.GetLink(queryLink)); } } else { return Util.CreateUri(baseUriWithSlash, this.GetLink(queryLink)); } } ///is the entity the same as the source or target entity /// related end ///true if same as source or target entity internal bool IsRelatedEntity(LinkDescriptor related) { return ((this.entity == related.Source) || (this.entity == related.Target)); } ////// Return the related end for this resource. One should call this method, only if the resource is inserted via deep resource. /// ///returns the related end via which the resource was inserted. internal LinkDescriptor GetRelatedEnd() { Debug.Assert(this.IsDeepInsert, "For related end, this must be a deep insert"); Debug.Assert(this.Identity == null, "If the identity is set, it means that the edit link no longer has the property name"); return new LinkDescriptor(this.parentDescriptor.entity, this.parentProperty, this.entity); } ////// Closes the save stream if there's any and sets it to null /// internal void CloseSaveStream() { if (this.saveStream != null) { DataServiceContext.DataServiceSaveStream stream = this.saveStream; this.saveStream = null; stream.Close(); } } ////// Returns the absolute URI for the media resource associated with this entity /// /// The base uri of the service. ///Absolute URI of the media resource for this entity, or null if the entity is not an MLE. internal Uri GetMediaResourceUri(Uri serviceBaseUri) { return this.ReadStreamUri == null ? null : Util.CreateUri(serviceBaseUri, this.ReadStreamUri); } ////// Returns the absolute URI for editing the media resource associated with this entity /// /// The base uri of the service. ///Absolute URI for editing the media resource for this entity, or null if the entity is not an MLE. internal Uri GetEditMediaResourceUri(Uri serviceBaseUri) { return this.EditStreamUri == null ? null : Util.CreateUri(serviceBaseUri, this.EditStreamUri); } ////// In V1, we used to not support self links. Hence we used to use edit links as self links. /// IN V2, we are adding support for self links. But if there are not specified, we need to /// fall back on the edit link. /// /// whether to get query link or the edit link. ///the query or the edit link, as specified in the private Uri GetLink(bool queryLink) { // If asked for a self link and self-link is present, return self link if (queryLink && this.SelfLink != null) { return this.SelfLink; } // otherwise return edit link if present. if (this.EditLink != null) { return this.EditLink; } // If both self and edit links are not specified, the entity must be in added state, and we need // to compute the relative link from the entity set name or the parent property. Debug.Assert(this.State == EntityStates.Added, "the entity must be in added state"); if (!String.IsNullOrEmpty(this.entitySetName)) { return Util.CreateUri(this.entitySetName, UriKind.Relative); } else { return Util.CreateUri(this.parentProperty, UriKind.Relative); } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.parameter.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- UriTemplatePathPartiallyEquivalentSet.cs
- ObjectQueryProvider.cs
- SqlInternalConnectionSmi.cs
- AggregationMinMaxHelpers.cs
- Int32CollectionConverter.cs
- BaseComponentEditor.cs
- RegisteredHiddenField.cs
- CodeSnippetCompileUnit.cs
- WeakReference.cs
- XmlSchemaExporter.cs
- Pool.cs
- AnimationTimeline.cs
- GenericWebPart.cs
- OleDbCommandBuilder.cs
- _Connection.cs
- EnvelopedSignatureTransform.cs
- XmlQuerySequence.cs
- RoleServiceManager.cs
- ConfigurationSectionCollection.cs
- Point.cs
- TypePresenter.xaml.cs
- DataGridViewToolTip.cs
- IPPacketInformation.cs
- SafeHandles.cs
- DefaultTraceListener.cs
- PackagingUtilities.cs
- DrawingState.cs
- ValidatorUtils.cs
- DesignerEditorPartChrome.cs
- GridSplitterAutomationPeer.cs
- DataGridViewCellEventArgs.cs
- ConfigurationSection.cs
- ComplusEndpointConfigContainer.cs
- latinshape.cs
- ResourcePart.cs
- DataGridViewAutoSizeModeEventArgs.cs
- EqualityComparer.cs
- DispatcherSynchronizationContext.cs
- DBDataPermission.cs
- RoutedPropertyChangedEventArgs.cs
- XmlResolver.cs
- DataExpression.cs
- XmlBinaryReaderSession.cs
- DesignBindingEditor.cs
- Deflater.cs
- TextRangeBase.cs
- TriggerAction.cs
- LayeredChannelFactory.cs
- ExpressionBuilder.cs
- NamespaceTable.cs
- ElementAction.cs
- SqlWorkflowPersistenceService.cs
- SqlFacetAttribute.cs
- ConnectionPoint.cs
- FixedSOMTable.cs
- UpdateTranslator.cs
- SqlCommandAsyncResult.cs
- DummyDataSource.cs
- StatusInfoItem.cs
- DataControlButton.cs
- XsdSchemaFileEditor.cs
- InternalsVisibleToAttribute.cs
- ValidatorCollection.cs
- EnglishPluralizationService.cs
- Logging.cs
- _OverlappedAsyncResult.cs
- URIFormatException.cs
- UidManager.cs
- DataGridViewRowCancelEventArgs.cs
- listitem.cs
- ToolStripLocationCancelEventArgs.cs
- ValidatedControlConverter.cs
- __Filters.cs
- DoWorkEventArgs.cs
- IDQuery.cs
- DoubleMinMaxAggregationOperator.cs
- OrderPreservingPipeliningMergeHelper.cs
- OneToOneMappingSerializer.cs
- Int32AnimationBase.cs
- MouseGestureValueSerializer.cs
- WebResourceAttribute.cs
- SiteMapNodeItemEventArgs.cs
- InvalidCastException.cs
- SweepDirectionValidation.cs
- ContentFileHelper.cs
- UnknownWrapper.cs
- RootBrowserWindow.cs
- IPipelineRuntime.cs
- PostBackOptions.cs
- LocatorPartList.cs
- FieldBuilder.cs
- URLBuilder.cs
- AsymmetricAlgorithm.cs
- ProcessStartInfo.cs
- SafeLocalMemHandle.cs
- XmlHierarchicalEnumerable.cs
- ApplicationContext.cs
- IBuiltInEvidence.cs
- DeploymentSection.cs
- LoginUtil.cs