/// <summary> /// Applies the values of a nested <paramref name="feed"/> to the collection /// <paramref name="property"/> of the specified <paramref name="entry"/>. /// </summary> /// <param name="entry">Entry with collection to be modified.</param> /// <param name="property">Collection property on the entry.</param> /// <param name="feed">Values to apply onto the collection.</param> /// <param name="includeLinks">Whether links that are expanded should be materialized.</param> private void ApplyFeedToCollection( MaterializerEntry entry, ClientPropertyAnnotation property, ODataFeed feed, bool includeLinks) { Debug.Assert(entry.Entry != null, "entry != null"); Debug.Assert(property != null, "property != null"); Debug.Assert(feed != null, "feed != null"); ClientEdmModel edmModel = this.MaterializerContext.Model; ClientTypeAnnotation collectionType = edmModel.GetClientTypeAnnotation(edmModel.GetOrCreateEdmType(property.EntityCollectionItemType)); IEnumerable <ODataEntry> entries = MaterializerFeed.GetFeed(feed).Entries; foreach (ODataEntry feedEntry in entries) { this.Materialize(MaterializerEntry.GetEntry(feedEntry), collectionType.ElementType, includeLinks); } ProjectionPlan continuationPlan = includeLinks ? ODataEntityMaterializer.CreatePlanForDirectMaterialization(property.EntityCollectionItemType) : ODataEntityMaterializer.CreatePlanForShallowMaterialization(property.EntityCollectionItemType); this.ApplyItemsToCollection( entry, property, entries.Select(e => MaterializerEntry.GetEntry(e).ResolvedObject), feed.NextPageLink, continuationPlan, false); }
private MaterializerEntry ReadEntryCore() { MaterializerEntry entry2; this.ExpectState(ODataReaderState.EntryStart); ODataEntry item = (ODataEntry)this.reader.Item; if (item == null) { entry2 = MaterializerEntry.CreateEmpty(); this.ReadAndExpectState(ODataReaderState.EntryEnd); return(entry2); } entry2 = MaterializerEntry.CreateEntry(item, this.responseInfo.MaxProtocolVersion); do { this.AssertRead(); switch (this.reader.State) { case ODataReaderState.EntryEnd: break; case ODataReaderState.NavigationLinkStart: entry2.AddNavigationLink(this.ReadNavigationLink()); break; default: throw System.Data.Services.Client.Error.InternalError(InternalError.UnexpectedReadState); } }while (this.reader.State != ODataReaderState.EntryEnd); entry2.UpdateEntityDescriptor(); return(entry2); }
internal static MaterializerEntry ParseSingleEntityPayload(IODataResponseMessage message, ResponseInfo responseInfo, Type expectedType) { ODataPayloadKind payloadKind = ODataPayloadKind.Entry; using (ODataMessageReader reader = ODataMaterializer.CreateODataMessageReader(message, responseInfo, false, ref payloadKind)) { IEdmType orCreateEdmType = ClientEdmModel.GetModel(responseInfo.MaxProtocolVersion).GetOrCreateEdmType(expectedType); ODataReader reader2 = ODataMaterializer.CreateODataReader(reader, payloadKind, orCreateEdmType, responseInfo.MaxProtocolVersion); ODataFeedOrEntryReader reader3 = new ODataFeedOrEntryReader(reader2, responseInfo); ODataEntry currentEntry = null; bool flag = false; while (reader3.Read()) { flag |= reader3.CurrentFeed != null; if (reader3.CurrentEntry != null) { if (currentEntry != null) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomParser_SingleEntry_MultipleFound); } currentEntry = reader3.CurrentEntry; } } if (currentEntry == null) { if (flag) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomParser_SingleEntry_NoneFound); } throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomParser_SingleEntry_ExpectedFeedOrEntry); } return(MaterializerEntry.GetEntry(currentEntry)); } }
/// <summary>Projects a simple value from the specified <paramref name="path"/>.</summary> /// <param name="materializer">Materializer under which projection is taking place.</param> /// <param name="entry">Root entry for paths.</param> /// <param name="expectedType">Expected type for <paramref name="entry"/>.</param> /// <param name="path">Path to pull value for.</param> /// <returns>The value for the specified <paramref name="path"/>.</returns> /// <remarks> /// This method will not instantiate entity types, except to satisfy requests /// for payload-driven feeds or leaf entities. /// </remarks> internal static object ProjectionValueForPath(object materializer, object entry, Type expectedType, object path) { Debug.Assert(typeof(ODataEntityMaterializer).IsAssignableFrom(materializer.GetType()), "typeof(ODataEntityMaterializer).IsAssignableFrom(materializer.GetType())"); Debug.Assert(entry.GetType() == typeof(ODataEntry), "entry.GetType() == typeof(ODataEntry)"); Debug.Assert(path.GetType() == typeof(ProjectionPath), "path.GetType() == typeof(ProjectionPath)"); return(((ODataEntityMaterializer)materializer).ProjectionValueForPath(MaterializerEntry.GetEntry((ODataEntry)entry), expectedType, (ProjectionPath)path)); }
private bool TryReadFeedOrEntry(bool lazy, out ODataFeed feed, out MaterializerEntry entry) { if (this.TryStartReadFeedOrEntry()) { if (this.reader.State == ODataReaderState.EntryStart) { entry = this.ReadEntryCore(); feed = null; } else { entry = null; feed = this.ReadFeedCore(lazy); } } else { feed = null; entry = null; } if (feed == null) { return(entry != null); } return(true); }
/// <summary>Tries to resolve the object as one from the context (only if tracking is enabled).</summary> /// <param name="entry">Entry to resolve.</param> /// <param name="expectedEntryType">Expected entry type for the specified <paramref name="entry"/>.</param> /// <returns>true if the entity was resolved; false otherwise.</returns> private bool TryResolveFromContext(MaterializerEntry entry, Type expectedEntryType) { Debug.Assert(entry.IsAtomOrTracking, "Should not be trying to resolve the entry from the context if entry.IsAtomOrTracking is false."); // We should either create a new instance or grab one from the context. if (this.MergeOption != MergeOption.NoTracking) { EntityStates state; entry.ResolvedObject = this.EntityTracker.TryGetEntity(entry.Id, out state); if (entry.ResolvedObject != null) { if (!expectedEntryType.IsInstanceOfType(entry.ResolvedObject)) { throw DSClient.Error.InvalidOperation(DSClient.Strings.Deserialize_Current(expectedEntryType, entry.ResolvedObject.GetType())); } ClientEdmModel edmModel = this.Model; entry.ActualType = edmModel.GetClientTypeAnnotation(edmModel.GetOrCreateEdmType(entry.ResolvedObject.GetType())); entry.EntityHasBeenResolved = true; // Note that deleted items will have their properties overwritten even // if PreserveChanges is used as a merge option. entry.ShouldUpdateFromPayload = this.MergeOption == MergeOption.OverwriteChanges || (this.MergeOption == MergeOption.PreserveChanges && state == EntityStates.Unchanged) || (this.MergeOption == MergeOption.PreserveChanges && state == EntityStates.Deleted); this.MaterializationLog.FoundExistingInstance(entry); return(true); } } return(false); }
private static void CheckEntryToAccessNotNull(MaterializerEntry entry, string name) { if (entry.Entry == null) { throw new NullReferenceException(System.Data.Services.Client.Strings.AtomMaterializer_EntryToAccessIsNull(name)); } }
internal void AddedLink(MaterializerEntry source, string propertyName, object target) { if (this.Tracking && (ShouldTrackWithContext(source) && ShouldTrackWithContext(target, this.responseInfo.MaxProtocolVersion))) { LinkDescriptor item = new LinkDescriptor(source.ResolvedObject, propertyName, target, EntityStates.Added); this.links.Add(item); } }
/// <summary>Checks whether the entity on the specified <paramref name="path"/> is null.</summary> /// <param name="entry">Root entry for paths.</param> /// <param name="expectedType">Expected type for <paramref name="entry"/>.</param> /// <param name="path">Path to pull value for.</param> /// <returns>Whether the specified <paramref name="path"/> is null.</returns> /// <remarks> /// This method will not instantiate entity types on the path. /// </remarks> internal static bool ProjectionCheckValueForPathIsNull( object entry, Type expectedType, object path) { Debug.Assert(entry.GetType() == typeof(ODataEntry), "entry.GetType() == typeof(ODataEntry)"); Debug.Assert(path.GetType() == typeof(ProjectionPath), "path.GetType() == typeof(ProjectionPath)"); return(ODataEntityMaterializer.ProjectionCheckValueForPathIsNull(MaterializerEntry.GetEntry((ODataEntry)entry), expectedType, (ProjectionPath)path)); }
/// <summary> /// Creates the materializer entry. /// </summary> /// <param name="entry">The entry.</param> /// <param name="format">The format the entry was read in.</param> /// <param name="isTracking">True if the contents of the entry will be tracked in the context, otherwise False.</param> /// <param name="model">The client model.</param> /// <returns>A new materializer entry.</returns> public static MaterializerEntry CreateEntry(ODataEntry entry, ODataFormat format, bool isTracking, ClientEdmModel model) { Debug.Assert(entry.GetAnnotation <MaterializerEntry>() == null, "MaterializerEntry has already been created."); MaterializerEntry materializerEntry = new MaterializerEntry(entry, format, isTracking, model); entry.SetAnnotation <MaterializerEntry>(materializerEntry); return(materializerEntry); }
internal static ODataEntry ProjectionGetEntry(MaterializerEntry entry, string name) { MaterializerEntry entry2 = GetPropertyOrThrow(entry.NavigationLinks, name, entry.Id).Entry; if (entry2 == null) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_PropertyNotExpectedEntry(name, entry.Id)); } CheckEntryToAccessNotNull(entry2, name); return(entry2.Entry); }
private void ResolveByCreatingWithType(MaterializerEntry entry, Type type) { ClientEdmModel model = ClientEdmModel.GetModel(base.ResponseInfo.MaxProtocolVersion); entry.ActualType = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(type)); entry.ResolvedObject = Activator.CreateInstance(type); entry.CreatedByMaterializer = true; entry.ShouldUpdateFromPayload = true; entry.EntityHasBeenResolved = true; this.log.CreatedInstance(entry); }
private bool TryReadEntry(out MaterializerEntry entry) { if (this.TryStartReadFeedOrEntry()) { this.ExpectState(ODataReaderState.EntryStart); entry = this.ReadEntryCore(); return(true); } entry = null; return(false); }
/// <summary> /// Reads the remainder of an entry. /// </summary> /// <returns>An entry.</returns> private MaterializerEntry ReadEntryCore() { this.ExpectState(ODataReaderState.EntryStart); ODataEntry result = (ODataEntry)this.reader.Item; MaterializerEntry entry; List <ODataNavigationLink> navigationLinks = new List <ODataNavigationLink>(); if (result != null) { entry = MaterializerEntry.CreateEntry( result, this.readODataFormat, this.mergeOption != MergeOption.NoTracking, this.clientEdmModel); do { this.AssertRead(); switch (this.reader.State) { case ODataReaderState.NavigationLinkStart: // Cache the list of navigation links here but don't add them to the entry because all of the key properties may not be available yet. navigationLinks.Add(this.ReadNavigationLink()); break; case ODataReaderState.EntryEnd: break; default: throw DSClient.Error.InternalError(InternalError.UnexpectedReadState); } }while (this.reader.State != ODataReaderState.EntryEnd); entry.UpdateEntityDescriptor(); } else { entry = MaterializerEntry.CreateEmpty(); this.ReadAndExpectState(ODataReaderState.EntryEnd); } // Add the navigation links here now that all of the property values have been read and are available to build the links. foreach (ODataNavigationLink navigationLink in navigationLinks) { entry.AddNavigationLink(navigationLink); } return(entry); }
private void ApplyFeedToCollection(MaterializerEntry entry, ClientPropertyAnnotation property, ODataFeed feed, bool includeLinks) { ClientEdmModel model = ClientEdmModel.GetModel(base.ResponseInfo.MaxProtocolVersion); ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(property.EntityCollectionItemType)); IEnumerable <ODataEntry> entries = MaterializerFeed.GetFeed(feed).Entries; foreach (ODataEntry entry2 in entries) { this.Materialize(MaterializerEntry.GetEntry(entry2), clientTypeAnnotation.ElementType, includeLinks); } ProjectionPlan continuationPlan = includeLinks ? CreatePlanForDirectMaterialization(property.EntityCollectionItemType) : CreatePlanForShallowMaterialization(property.EntityCollectionItemType); this.ApplyItemsToCollection(entry, property, from e in entries select MaterializerEntry.GetEntry(e).ResolvedObject, feed.NextPageLink, continuationPlan); }
private void ResolveOrCreateInstance(MaterializerEntry entry, Type expectedEntryType) { if (!this.TryResolveAsTarget(entry)) { if (entry.Id == null) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Deserialize_MissingIdElement); } if (!this.TryResolveAsCreated(entry) && !this.TryResolveFromContext(entry, expectedEntryType)) { this.ResolveByCreating(entry, expectedEntryType); } } }
private bool TryResolveAsTarget(MaterializerEntry entry) { if (entry.ResolvedObject == null) { return(false); } ClientEdmModel model = ClientEdmModel.GetModel(base.ResponseInfo.MaxProtocolVersion); entry.ActualType = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entry.ResolvedObject.GetType())); this.log.FoundTargetInstance(entry); entry.ShouldUpdateFromPayload = this.mergeOption != MergeOption.PreserveChanges; entry.EntityHasBeenResolved = true; return(true); }
public static MaterializerEntry CreateEntry(ODataEntry entry, DataServiceProtocolVersion maxProtocolVersion) { MaterializerEntry annotation = new MaterializerEntry(entry, maxProtocolVersion); entry.SetAnnotation<MaterializerEntry>(annotation); if (entry.Id == null) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Deserialize_MissingIdElement); } annotation.EntityDescriptor.Identity = entry.Id; annotation.EntityDescriptor.EditLink = entry.EditLink; annotation.EntityDescriptor.SelfLink = entry.ReadLink; annotation.EntityDescriptor.ETag = entry.ETag; return annotation; }
private static void MaterializeToList(ODataEntityMaterializer materializer, IEnumerable list, Type nestedExpectedType, IEnumerable <ODataEntry> entries) { Action <object, object> addToCollectionDelegate = ODataMaterializer.GetAddToCollectionDelegate(list.GetType()); foreach (ODataEntry entry in entries) { MaterializerEntry entry2 = MaterializerEntry.GetEntry(entry); if (!entry2.EntityHasBeenResolved) { materializer.Materialize(entry2, nestedExpectedType, false); } addToCollectionDelegate(list, entry2.ResolvedObject); } }
private void ApplyItemsToCollection(MaterializerEntry entry, ClientPropertyAnnotation property, IEnumerable items, Uri nextLink, ProjectionPlan continuationPlan) { Func <LinkDescriptor, bool> predicate = null; object instance = entry.ShouldUpdateFromPayload ? GetOrCreateCollectionProperty(entry.ResolvedObject, property, null) : null; ClientEdmModel model = ClientEdmModel.GetModel(base.ResponseInfo.MaxProtocolVersion); ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(property.EntityCollectionItemType)); foreach (object obj3 in items) { if (!clientTypeAnnotation.ElementType.IsAssignableFrom(obj3.GetType())) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_EntryIntoCollectionMismatch(obj3.GetType().FullName, clientTypeAnnotation.ElementType.FullName)); } if (entry.ShouldUpdateFromPayload) { property.SetValue(instance, obj3, property.PropertyName, true); this.log.AddedLink(entry, property.PropertyName, obj3); } } if (entry.ShouldUpdateFromPayload) { this.FoundNextLinkForCollection(instance as IEnumerable, nextLink, continuationPlan); } else { this.FoundNextLinkForUnmodifiedCollection(property.GetValue(entry.ResolvedObject) as IEnumerable); } if ((this.mergeOption == MergeOption.OverwriteChanges) || (this.mergeOption == MergeOption.PreserveChanges)) { if (predicate == null) { predicate = delegate(LinkDescriptor x) { if (MergeOption.OverwriteChanges != this.mergeOption) { return(EntityStates.Added != x.State); } return(true); }; } foreach (object obj4 in (from x in base.ResponseInfo.EntityTracker.GetLinks(entry.ResolvedObject, property.PropertyName).Where <LinkDescriptor>(predicate) select x.Target).Except <object>(EnumerateAsElementType <object>(items))) { if (instance != null) { property.RemoveValue(instance, obj4); } this.log.RemovedLink(entry, property.PropertyName, obj4); } } }
public static MaterializerEntry CreateEntry(ODataEntry entry, DataServiceProtocolVersion maxProtocolVersion) { MaterializerEntry annotation = new MaterializerEntry(entry, maxProtocolVersion); entry.SetAnnotation <MaterializerEntry>(annotation); if (entry.Id == null) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Deserialize_MissingIdElement); } annotation.EntityDescriptor.Identity = entry.Id; annotation.EntityDescriptor.EditLink = entry.EditLink; annotation.EntityDescriptor.SelfLink = entry.ReadLink; annotation.EntityDescriptor.ETag = entry.ETag; return(annotation); }
private bool TryResolveAsCreated(MaterializerEntry entry) { MaterializerEntry entry2; if (!this.log.TryResolve(entry, out entry2)) { return(false); } entry.ActualType = entry2.ActualType; entry.ResolvedObject = entry2.ResolvedObject; entry.CreatedByMaterializer = entry2.CreatedByMaterializer; entry.ShouldUpdateFromPayload = entry2.ShouldUpdateFromPayload; entry.EntityHasBeenResolved = true; return(true); }
protected sealed override bool ReadImplementation() { base.nextLinkTable.Clear(); if (!this.ReadNextFeedOrEntry()) { return(false); } if (((this.CurrentEntry == null) && (this.CurrentFeed != null)) && !this.ReadNextFeedOrEntry()) { return(false); } MaterializerEntry.GetEntry(this.CurrentEntry).ResolvedObject = this.TargetInstance; this.currentValue = this.materializeEntryPlan.Run(this, this.CurrentEntry, base.ExpectedType); return(true); }
private void MergeLists(MaterializerEntry entry, ClientPropertyAnnotation property, IEnumerable list, Uri nextLink, ProjectionPlan plan) { if ((entry.ShouldUpdateFromPayload && (property.NullablePropertyType == list.GetType())) && (property.GetValue(entry.ResolvedObject) == null)) { property.SetValue(entry.ResolvedObject, list, property.PropertyName, false); this.FoundNextLinkForCollection(list, nextLink, plan); foreach (object obj2 in list) { this.log.AddedLink(entry, property.PropertyName, obj2); } } else { this.ApplyItemsToCollection(entry, property, list, nextLink, plan); } }
/// <summary> /// Tries to resolve the specified entry as an entry that has already been created in this materialization session or is already in the context. /// </summary> /// <param name="entry">Entry to resolve.</param> /// <param name="expectedEntryType">Expected type of the entry.</param> /// <returns>True if the entry was resolved, otherwise False.</returns> internal bool TryResolveAsExistingEntry(MaterializerEntry entry, Type expectedEntryType) { // Resolution is based on the entry Id, so if we can't use that property, we don't even need to try to resolve it. if (entry.IsAtomOrTracking) { // The resolver methods below will both need access to Id, so first ensure it's not null if (entry.Id == null) { throw DSClient.Error.InvalidOperation(DSClient.Strings.Deserialize_MissingIdElement); } return(this.TryResolveAsCreated(entry) || this.TryResolveFromContext(entry, expectedEntryType)); } return(false); }
/// <summary> /// Populates the collection property on the entry's resolved object with the given items enumerator. /// </summary> /// <param name="entry">Entry with collection to be modified.</param> /// <param name="property">Collection property on the entry.</param> /// <param name="items">Values to apply onto the collection.</param> /// <param name="nextLink">Next link for collection continuation.</param> /// <param name="continuationPlan">Projection plan for collection continuation.</param> /// <returns>Collection instance that was populated.</returns> private object PopulateCollectionProperty( MaterializerEntry entry, ClientPropertyAnnotation property, IEnumerable <object> items, Uri nextLink, ProjectionPlan continuationPlan) { Debug.Assert(entry.Entry != null || entry.ForLoadProperty, "ODataEntry should be non-null except for LoadProperty"); Debug.Assert(property != null, "property != null"); Debug.Assert(items != null, "items != null"); object collection = null; ClientEdmModel edmModel = this.MaterializerContext.Model; ClientTypeAnnotation collectionType = edmModel.GetClientTypeAnnotation(edmModel.GetOrCreateEdmType(property.EntityCollectionItemType)); if (entry.ShouldUpdateFromPayload) { collection = this.GetOrCreateCollectionProperty(entry.ResolvedObject, property, entry.ForLoadProperty); foreach (object item in items) { // Validate that item can be inserted into collection. ValidateCollectionElementTypeIsItemType(item.GetType(), collectionType.ElementType); property.SetValue(collection, item, property.PropertyName, true /* allowAdd? */); this.EntityTrackingAdapter.MaterializationLog.AddedLink(entry, property.PropertyName, item); } this.FoundNextLinkForCollection(collection as IEnumerable, nextLink, continuationPlan); } else { Debug.Assert(!entry.ForLoadProperty, "LoadProperty should always have ShouldUpateForPayload set to true."); foreach (object item in items) { // Validate that item can be inserted into collection. ValidateCollectionElementTypeIsItemType(item.GetType(), collectionType.ElementType); } this.FoundNextLinkForUnmodifiedCollection(property.GetValue(entry.ResolvedObject) as IEnumerable); } return(collection); }
/// <summary>"Resolved" the entity in the <paramref name="entry"/> by instantiating it.</summary> /// <param name="entry">Entry to resolve.</param> /// <param name="type">Type to create.</param> /// <remarks> /// After invocation, entry.ResolvedObject is exactly of type <paramref name="type"/>. /// </remarks> internal void ResolveByCreatingWithType(MaterializerEntry entry, Type type) { // TODO: CreateNewInstance needs to do all of these operations otherwise an inadvertent call to CreateNewInstance // will create a new entity instance that is not tracked in the context or materialization log. Will need to change this // prior to shipping if public Debug.Assert( entry.ResolvedObject == null, "entry.ResolvedObject == null -- otherwise we're about to overwrite - should never be called"); ClientEdmModel edmModel = this.MaterializerContext.Model; entry.ActualType = edmModel.GetClientTypeAnnotation(edmModel.GetOrCreateEdmType(type)); entry.ResolvedObject = this.CreateNewInstance(entry.ActualType.EdmTypeReference, type); entry.CreatedByMaterializer = true; entry.ShouldUpdateFromPayload = true; entry.EntityHasBeenResolved = true; this.EntityTrackingAdapter.MaterializationLog.CreatedInstance(entry); }
private static void ApplyLinkProperties(ClientTypeAnnotation actualType, MaterializerEntry entry) { if (entry.ShouldUpdateFromPayload) { foreach (ClientPropertyAnnotation annotation in from p in actualType.Properties() where p.PropertyType == typeof(DataServiceStreamLink) select p) { StreamDescriptor descriptor; string propertyName = annotation.PropertyName; if (entry.EntityDescriptor.TryGetNamedStreamInfo(propertyName, out descriptor)) { annotation.SetValue(entry.ResolvedObject, descriptor.StreamLink, propertyName, true); } } } }
/// <summary>Resolved or creates an instance on the specified <paramref name="entry"/>.</summary> /// <param name="entry">Entry on which to resolve or create an instance.</param> /// <param name="expectedEntryType">Expected type for the <paramref name="entry"/>.</param> /// <remarks> /// After invocation, the ResolvedObject value of the <paramref name="entry"/> /// will be assigned, along with the ActualType value. /// </remarks> /// <returns>True if an existing entity is found.</returns> internal virtual bool TryResolveExistingEntity(MaterializerEntry entry, Type expectedEntryType) { Debug.Assert(entry.Entry != null, "entry != null"); Debug.Assert(expectedEntryType != null, "expectedEntryType != null"); Debug.Assert(entry.EntityHasBeenResolved == false, "entry.EntityHasBeenResolved == false"); // This will be the case when TargetInstance has been set. if (this.TryResolveAsTarget(entry)) { return(true); } if (this.TryResolveAsExistingEntry(entry, expectedEntryType)) { return(true); } return(false); }
/// <summary> /// This method is for parsing CUD operation payloads which should contain /// 1 a single entry /// 2 An Error /// </summary> /// <param name="message">the message for the payload</param> /// <param name="responseInfo">The current ResponseInfo object</param> /// <param name="expectedType">The expected type</param> /// <returns>the MaterializerEntry that was read</returns> internal static MaterializerEntry ParseSingleEntityPayload(IODataResponseMessage message, ResponseInfo responseInfo, Type expectedType) { ODataPayloadKind messageType = ODataPayloadKind.Entry; using (ODataMessageReader messageReader = CreateODataMessageReader(message, responseInfo, ref messageType)) { IEdmType edmType = responseInfo.TypeResolver.ResolveExpectedTypeForReading(expectedType); ODataReaderWrapper reader = ODataReaderWrapper.Create(messageReader, messageType, edmType, responseInfo.ResponsePipeline); FeedAndEntryMaterializerAdapter parser = new FeedAndEntryMaterializerAdapter(messageReader, reader, responseInfo.Model, responseInfo.MergeOption); ODataEntry entry = null; bool readFeed = false; while (parser.Read()) { readFeed |= parser.CurrentFeed != null; if (parser.CurrentEntry != null) { if (entry != null) { throw new InvalidOperationException(DSClient.Strings.AtomParser_SingleEntry_MultipleFound); } entry = parser.CurrentEntry; } } if (entry == null) { if (readFeed) { throw new InvalidOperationException(DSClient.Strings.AtomParser_SingleEntry_NoneFound); } else { throw new InvalidOperationException(DSClient.Strings.AtomParser_SingleEntry_ExpectedFeedOrEntry); } } return(MaterializerEntry.GetEntry(entry)); } }
/// <summary>Tries to resolve the object from those created in this materialization session.</summary> /// <param name="entry">Entry to resolve.</param> /// <returns>true if the entity was resolved; false otherwise.</returns> private bool TryResolveAsCreated(MaterializerEntry entry) { Debug.Assert(entry.IsAtomOrTracking, "Should not be trying to resolve the entry from the current materialization session if entry.IsAtomOrTracking is false."); MaterializerEntry existingEntry; if (!this.MaterializationLog.TryResolve(entry, out existingEntry)) { return(false); } Debug.Assert( existingEntry.ResolvedObject != null, "existingEntry.ResolvedObject != null -- how did it get there otherwise?"); entry.ActualType = existingEntry.ActualType; entry.ResolvedObject = existingEntry.ResolvedObject; entry.CreatedByMaterializer = existingEntry.CreatedByMaterializer; entry.ShouldUpdateFromPayload = existingEntry.ShouldUpdateFromPayload; entry.EntityHasBeenResolved = true; return(true); }
private bool TryResolveFromContext(MaterializerEntry entry, Type expectedEntryType) { if (this.mergeOption != MergeOption.NoTracking) { EntityStates states; entry.ResolvedObject = base.ResponseInfo.EntityTracker.TryGetEntity(entry.Id, out states); if (entry.ResolvedObject != null) { if (!expectedEntryType.IsInstanceOfType(entry.ResolvedObject)) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Deserialize_Current(expectedEntryType, entry.ResolvedObject.GetType())); } ClientEdmModel model = ClientEdmModel.GetModel(base.ResponseInfo.MaxProtocolVersion); entry.ActualType = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entry.ResolvedObject.GetType())); entry.EntityHasBeenResolved = true; entry.ShouldUpdateFromPayload = ((this.mergeOption == MergeOption.OverwriteChanges) || ((this.mergeOption == MergeOption.PreserveChanges) && (states == EntityStates.Unchanged))) || ((this.mergeOption == MergeOption.PreserveChanges) && (states == EntityStates.Deleted)); this.log.FoundExistingInstance(entry); return(true); } } return(false); }
public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, MaterializerEntry entry) { MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, entry); link.SetAnnotation<MaterializerNavigationLink>(annotation); return annotation; }
private static bool ShouldTrackWithContext(MaterializerEntry entry) { return entry.ActualType.IsEntityType; }
internal bool TryResolve(MaterializerEntry entry, out MaterializerEntry existingEntry) { ODataEntry entry2; if (this.identityStack.TryGetValue(entry.Id, out entry2)) { existingEntry = MaterializerEntry.GetEntry(entry2); return true; } if (this.appendOnlyEntries.TryGetValue(entry.Id, out entry2)) { EntityStates states; this.responseInfo.EntityTracker.TryGetEntity(entry.Id, out states); if (states == EntityStates.Unchanged) { existingEntry = MaterializerEntry.GetEntry(entry2); return true; } this.appendOnlyEntries.Remove(entry.Id); } existingEntry = null; return false; }
internal void FoundTargetInstance(MaterializerEntry entry) { if (ShouldTrackWithContext(entry)) { this.responseInfo.EntityTracker.AttachIdentity(entry.EntityDescriptor, this.mergeOption); this.identityStack.Add(entry.Id, entry.Entry); this.insertRefreshObject = entry.ResolvedObject; } }
internal void FoundExistingInstance(MaterializerEntry entry) { this.identityStack[entry.Id] = entry.Entry; }
internal void CreatedInstance(MaterializerEntry entry) { if (ShouldTrackWithContext(entry)) { this.identityStack.Add(entry.Id, entry.Entry); if (this.mergeOption == MergeOption.AppendOnly) { this.appendOnlyEntries.Add(entry.Id, entry.Entry); } } }
private bool TryReadFeedOrEntry(bool lazy, out ODataFeed feed, out MaterializerEntry entry) { if (this.TryStartReadFeedOrEntry()) { if (this.reader.State == ODataReaderState.EntryStart) { entry = this.ReadEntryCore(); feed = null; } else { entry = null; feed = this.ReadFeedCore(lazy); } } else { feed = null; entry = null; } if (feed == null) { return (entry != null); } return true; }
private bool TryReadEntry(out MaterializerEntry entry) { if (this.TryStartReadFeedOrEntry()) { this.ExpectState(ODataReaderState.EntryStart); entry = this.ReadEntryCore(); return true; } entry = null; return false; }