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 { 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 this.identity = identity; this.selfLink = selfLink; this.editLink = editLink; this.parentDescriptor = parentEntity; this.parentProperty = parentProperty; this.entity = entity; this.etag = etag; this.entitySetName = entitySetName; }
internal void RestoreParentState(EntityDescriptor parentDescriptor, string parentProperty) { this.parentDescriptor = parentDescriptor; this.parentProperty = parentProperty; }
internal void ApplyToContext() { Debug.Assert( this.mergeOption != MergeOption.OverwriteChanges || this.foundEntriesWithMedia.Count == 0, "mergeOption != MergeOption.OverwriteChanges || foundEntriesWithMedia.Count == 0 - we only use the 'entries-with-media' lookaside when we're not in overwrite mode, otherwise we track everything through identity stack"); if (!this.Tracking) { return; } foreach (KeyValuePair<string, AtomEntry> entity in this.identityStack) { AtomEntry entry = entity.Value; if (entry.CreatedByMaterializer || entry.ResolvedObject == this.insertRefreshObject || entry.ShouldUpdateFromPayload) { EntityDescriptor descriptor = new EntityDescriptor(entity.Key, entry.QueryLink, entry.EditLink, entry.ResolvedObject, null, null, null, entry.ETagText, EntityStates.Unchanged); descriptor = this.context.InternalAttachEntityDescriptor(descriptor, false); descriptor.State = EntityStates.Unchanged; this.ApplyMediaEntryInformation(entry, descriptor); descriptor.ServerTypeName = entry.TypeName; } else { EntityStates state; this.context.TryGetEntity(entity.Key, entry.ETagText, this.mergeOption, out state); } } foreach (AtomEntry entry in this.foundEntriesWithMedia.Values) { Debug.Assert(entry.ResolvedObject != null, "entry.ResolvedObject != null -- otherwise it wasn't found"); EntityDescriptor descriptor = this.context.GetEntityDescriptor(entry.ResolvedObject); this.ApplyMediaEntryInformation(entry, descriptor); } foreach (LinkDescriptor link in this.links) { if (EntityStates.Added == link.State) { if ((EntityStates.Deleted == this.context.GetEntityDescriptor(link.Target).State) || (EntityStates.Deleted == this.context.GetEntityDescriptor(link.Source).State)) { this.context.DeleteLink(link.Source, link.SourceProperty, link.Target); } else { this.context.AttachLink(link.Source, link.SourceProperty, link.Target, this.mergeOption); } } else if (EntityStates.Modified == link.State) { object target = link.Target; if (MergeOption.PreserveChanges == this.mergeOption) { LinkDescriptor end = this.context.GetLinks(link.Source, link.SourceProperty).FirstOrDefault(); if (null != end && null == end.Target) { continue; } if ((null != target && EntityStates.Deleted == this.context.GetEntityDescriptor(target).State) || EntityStates.Deleted == this.context.GetEntityDescriptor(link.Source).State) { target = null; } } this.context.AttachLink(link.Source, link.SourceProperty, target, this.mergeOption); } else { Debug.Assert(EntityStates.Detached == link.State, "not detached link"); this.context.DetachLink(link.Source, link.SourceProperty, link.Target); } } }
internal static EntityDescriptor RestoreState(EntityDescriptorState state) { SaveStreamState saveStreamState = state.SaveStream; DataServiceContext.DataServiceSaveStream saveStream = (saveStreamState != null) ? DataServiceContext.DataServiceSaveStream.RestoreState(saveStreamState) : null; var entityDescriptor = new EntityDescriptor( state.Identity, state.SelfLink, state.EditLink, state.Entity, null, null, state.EntitySetName, state.Etag, state.State) { editMediaLink = state.EditMediaLink, readStreamLink = state.ReadStreamLink, saveStream = saveStream, selfLink = state.SelfLink, serverTypeName = state.ServerTypeName, streamETag = state.StreamETag, streamState = state.StreamState, }; entityDescriptor.RestoreState((DescriptorState)state); return entityDescriptor; }
private void ApplyMediaEntryInformation(AtomEntry entry, EntityDescriptor descriptor) { Debug.Assert(entry != null, "entry != null"); Debug.Assert(descriptor != null, "descriptor != null"); if (entry.MediaEditUri != null || entry.MediaContentUri != null) { if (entry.MediaEditUri != null) { descriptor.EditStreamUri = new Uri(this.context.BaseUriWithSlash, entry.MediaEditUri); } if (entry.MediaContentUri != null) { descriptor.ReadStreamUri = new Uri(this.context.BaseUriWithSlash, entry.MediaContentUri); } descriptor.StreamETag = entry.StreamETagText; } }