public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, MaterializerEntry entry) { MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, entry); link.SetAnnotation <MaterializerNavigationLink>(annotation); return(annotation); }
/// <summary> /// Reads a navigation link. /// </summary> /// <returns>A navigation link.</returns> private ODataNavigationLink ReadNavigationLink() { Debug.Assert(this.reader.State == ODataReaderState.NavigationLinkStart, "this.reader.State == ODataReaderState.NavigationLinkStart"); ODataNavigationLink link = (ODataNavigationLink)this.reader.Item; MaterializerEntry entry; ODataFeed feed; if (this.TryReadFeedOrEntry(false, out feed, out entry)) { if (feed != null) { MaterializerNavigationLink.CreateLink(link, feed); } else { Debug.Assert(entry != null, "entry != null"); MaterializerNavigationLink.CreateLink(link, entry); } this.ReadAndExpectState(ODataReaderState.NavigationLinkEnd); } this.ExpectState(ODataReaderState.NavigationLinkEnd); return(link); }
public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, ODataFeed feed) { MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, feed); link.SetAnnotation <MaterializerNavigationLink>(annotation); return(annotation); }
/// <summary> /// Creates the materializer link with a feed. /// </summary> /// <param name="link">The link.</param> /// <param name="feed">The feed.</param> /// <returns>The materializer link.</returns> public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, ODataFeed feed) { Debug.Assert(link.GetAnnotation <MaterializerNavigationLink>() == null, "there should be no MaterializerNavigationLink annotation on the feed link yet"); MaterializerNavigationLink materializedNavigationLink = new MaterializerNavigationLink(link, feed); link.SetAnnotation <MaterializerNavigationLink>(materializedNavigationLink); return(materializedNavigationLink); }
internal static IEnumerable ProjectionSelect(ODataEntityMaterializer materializer, MaterializerEntry entry, Type expectedType, Type resultType, ProjectionPath path, Func <object, object, Type, object> selector) { ClientEdmModel model = ClientEdmModel.GetModel(materializer.ResponseInfo.MaxProtocolVersion); ClientTypeAnnotation clientTypeAnnotation = entry.ActualType ?? model.GetClientTypeAnnotation(model.GetOrCreateEdmType(expectedType)); IEnumerable enumerable = (IEnumerable)Util.ActivatorCreateInstance(typeof(List <>).MakeGenericType(new Type[] { resultType }), new object[0]); MaterializerNavigationLink link = null; ClientPropertyAnnotation property = null; for (int i = 0; i < path.Count; i++) { ProjectionPathSegment segment = path[i]; if (segment.SourceTypeAs != null) { clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(segment.SourceTypeAs)); } if (segment.Member != null) { string member = segment.Member; property = clientTypeAnnotation.GetProperty(member, false); link = GetPropertyOrThrow(entry.NavigationLinks, member, entry.Id); if (link.Entry != null) { entry = link.Entry; clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(property.PropertyType)); } } } ValidatePropertyMatch(property, link.Link); MaterializerFeed feed = MaterializerFeed.GetFeed(link.Feed); Action <object, object> addToCollectionDelegate = ODataMaterializer.GetAddToCollectionDelegate(enumerable.GetType()); foreach (ODataEntry entry2 in feed.Entries) { object obj2 = selector(materializer, entry2, property.EntityCollectionItemType); addToCollectionDelegate(enumerable, obj2); } ProjectionPlan plan = new ProjectionPlan { LastSegmentType = property.EntityCollectionItemType, Plan = selector, ProjectedType = resultType }; materializer.FoundNextLinkForCollection(enumerable, feed.NextPageLink, plan); return(enumerable); }
private static MaterializerNavigationLink GetPropertyOrThrow(IEnumerable <ODataNavigationLink> links, string propertyName, string entryIdentity) { Func <ODataNavigationLink, bool> predicate = null; ODataNavigationLink link = null; if (links != null) { if (predicate == null) { predicate = p => p.Name == propertyName; } link = links.Where <ODataNavigationLink>(predicate).FirstOrDefault <ODataNavigationLink>(); } if (link == null) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_PropertyMissing(propertyName, entryIdentity)); } return(MaterializerNavigationLink.GetLink(link)); }
private ODataNavigationLink ReadNavigationLink() { MaterializerEntry entry; ODataFeed feed; ODataNavigationLink item = (ODataNavigationLink)this.reader.Item; if (this.TryReadFeedOrEntry(false, out feed, out entry)) { if (feed != null) { MaterializerNavigationLink.CreateLink(item, feed); } else { MaterializerNavigationLink.CreateLink(item, entry); } this.ReadAndExpectState(ODataReaderState.NavigationLinkEnd); } this.ExpectState(ODataReaderState.NavigationLinkEnd); return(item); }
internal static object ProjectionValueForPath(ODataEntityMaterializer materializer, MaterializerEntry entry, Type expectedType, ProjectionPath path) { if ((path.Count == 0) || ((path.Count == 1) && (path[0].Member == null))) { if (!entry.EntityHasBeenResolved) { materializer.Materialize(entry, expectedType, false); } return(entry.ResolvedObject); } object streamLink = null; ODataNavigationLink link = null; ODataProperty atomProperty = null; ICollection <ODataNavigationLink> navigationLinks = entry.NavigationLinks; IEnumerable <ODataProperty> properties = entry.Entry.Properties; ClientEdmModel model = ClientEdmModel.GetModel(materializer.ResponseInfo.MaxProtocolVersion); for (int i = 0; i < path.Count; i++) { Func <StreamDescriptor, bool> predicate = null; Func <ODataNavigationLink, bool> func2 = null; Func <ODataProperty, bool> func3 = null; Func <ODataProperty, bool> func4 = null; Func <ODataNavigationLink, bool> func5 = null; string propertyName; ProjectionPathSegment segment = path[i]; if (segment.Member != null) { bool flag = i == (path.Count - 1); propertyName = segment.Member; expectedType = segment.SourceTypeAs ?? expectedType; ClientPropertyAnnotation property = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(expectedType)).GetProperty(propertyName, false); if (property.IsStreamLinkProperty) { if (predicate == null) { predicate = sd => sd.Name == propertyName; } StreamDescriptor descriptor = entry.EntityDescriptor.StreamDescriptors.Where <StreamDescriptor>(predicate).SingleOrDefault <StreamDescriptor>(); if (descriptor == null) { if (segment.SourceTypeAs == null) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_PropertyMissing(propertyName, entry.Entry.Id)); } return(WebUtil.GetDefaultValue <DataServiceStreamLink>()); } streamLink = descriptor.StreamLink; } else { if (segment.SourceTypeAs != null) { if (func2 == null) { func2 = p => p.Name == propertyName; } if (!navigationLinks.Any <ODataNavigationLink>(func2)) { if (func3 == null) { func3 = p => p.Name == propertyName; } if (!properties.Any <ODataProperty>(func3) && flag) { return(WebUtil.GetDefaultValue(property.PropertyType)); } } } if (func4 == null) { func4 = p => p.Name == propertyName; } atomProperty = properties.Where <ODataProperty>(func4).FirstOrDefault <ODataProperty>(); if (func5 == null) { func5 = p => p.Name == propertyName; } link = ((atomProperty == null) && (navigationLinks != null)) ? navigationLinks.Where <ODataNavigationLink>(func5).FirstOrDefault <ODataNavigationLink>() : null; if ((link == null) && (atomProperty == null)) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_PropertyMissing(propertyName, entry.Entry.Id)); } if (link != null) { ValidatePropertyMatch(property, link); MaterializerNavigationLink link2 = MaterializerNavigationLink.GetLink(link); if (link2.Feed != null) { MaterializerFeed feed = MaterializerFeed.GetFeed(link2.Feed); Type implementationType = ClientTypeUtil.GetImplementationType(segment.ProjectionType, typeof(ICollection <>)); if (implementationType == null) { implementationType = ClientTypeUtil.GetImplementationType(segment.ProjectionType, typeof(IEnumerable <>)); } Type nestedExpectedType = implementationType.GetGenericArguments()[0]; Type projectionType = segment.ProjectionType; if (projectionType.IsInterfaceEx() || ODataMaterializer.IsDataServiceCollection(projectionType)) { projectionType = typeof(Collection <>).MakeGenericType(new Type[] { nestedExpectedType }); } IEnumerable list = (IEnumerable)Util.ActivatorCreateInstance(projectionType, new object[0]); MaterializeToList(materializer, list, nestedExpectedType, feed.Entries); if (ODataMaterializer.IsDataServiceCollection(segment.ProjectionType)) { list = (IEnumerable)Util.ActivatorCreateInstance(WebUtil.GetDataServiceCollectionOfT(new Type[] { nestedExpectedType }), new object[] { list, TrackingMode.None }); } ProjectionPlan plan = CreatePlanForShallowMaterialization(nestedExpectedType); materializer.FoundNextLinkForCollection(list, feed.Feed.NextPageLink, plan); streamLink = list; } else if (link2.Entry != null) { MaterializerEntry entry2 = link2.Entry; if (flag) { if ((entry2.Entry != null) && !entry2.EntityHasBeenResolved) { materializer.Materialize(entry2, property.PropertyType, false); } } else { CheckEntryToAccessNotNull(entry2, propertyName); } properties = entry2.Properties; navigationLinks = entry2.NavigationLinks; streamLink = entry2.ResolvedObject; entry = entry2; } } else { if (atomProperty.Value is ODataStreamReferenceValue) { streamLink = null; navigationLinks = ODataMaterializer.EmptyLinks; properties = ODataMaterializer.EmptyProperties; continue; } ValidatePropertyMatch(property, atomProperty); if (ClientTypeUtil.TypeOrElementTypeIsEntity(property.PropertyType)) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidEntityType(property.EntityCollectionItemType ?? property.PropertyType)); } if (property.IsPrimitiveOrComplexCollection) { object instance = streamLink ?? (entry.ResolvedObject ?? Util.ActivatorCreateInstance(expectedType, new object[0])); ODataMaterializer.ApplyDataValue(model.GetClientTypeAnnotation(model.GetOrCreateEdmType(instance.GetType())), atomProperty, materializer.ResponseInfo.IgnoreMissingProperties, materializer.ResponseInfo, instance); navigationLinks = ODataMaterializer.EmptyLinks; properties = ODataMaterializer.EmptyProperties; } else if (atomProperty.Value is ODataComplexValue) { ODataComplexValue complexValue = atomProperty.Value as ODataComplexValue; ODataMaterializer.MaterializeComplexTypeProperty(property.PropertyType, complexValue, materializer.ResponseInfo.IgnoreMissingProperties, materializer.ResponseInfo); properties = complexValue.Properties; navigationLinks = ODataMaterializer.EmptyLinks; } else { if ((atomProperty.Value == null) && !ClientTypeUtil.CanAssignNull(property.NullablePropertyType)) { throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_CannotAssignNull(atomProperty.Name, property.NullablePropertyType)); } ODataMaterializer.MaterializePrimitiveDataValue(property.NullablePropertyType, atomProperty); navigationLinks = ODataMaterializer.EmptyLinks; properties = ODataMaterializer.EmptyProperties; } streamLink = atomProperty.GetMaterializedValue(); } } expectedType = property.PropertyType; } } return(streamLink); }
internal static bool ProjectionCheckValueForPathIsNull(MaterializerEntry entry, Type expectedType, ProjectionPath path) { if ((path.Count == 0) || ((path.Count == 1) && (path[0].Member == null))) { return(entry.Entry == null); } bool flag = false; MaterializerNavigationLink link = null; IEnumerable <ODataNavigationLink> navigationLinks = entry.NavigationLinks; ClientEdmModel model = ClientEdmModel.GetModel(entry.EntityDescriptor.MaxProtocolVersion); for (int i = 0; i < path.Count; i++) { Func <ODataNavigationLink, bool> predicate = null; string propertyName; ProjectionPathSegment segment = path[i]; if (segment.Member != null) { bool flag2 = i == (path.Count - 1); propertyName = segment.Member; if (segment.SourceTypeAs != null) { expectedType = segment.SourceTypeAs; if (predicate == null) { predicate = p => p.Name == propertyName; } if (!navigationLinks.Any <ODataNavigationLink>(predicate)) { return(true); } } IEdmType orCreateEdmType = model.GetOrCreateEdmType(expectedType); ClientPropertyAnnotation property = model.GetClientTypeAnnotation(orCreateEdmType).GetProperty(propertyName, false); link = GetPropertyOrThrow(navigationLinks, propertyName, entry.Id); ValidatePropertyMatch(property, link.Link); if (link.Feed != null) { flag = false; } else { if (link.Entry == null) { return(true); } if (flag2) { flag = link.Entry.Entry == null; } else { entry = link.Entry; navigationLinks = entry.NavigationLinks; } } expectedType = property.PropertyType; } } return(flag); }
private void MaterializeResolvedEntry(MaterializerEntry entry, bool includeLinks) { ClientTypeAnnotation actualType = entry.ActualType; if (!actualType.IsEntityType) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidNonEntityType(actualType.ElementTypeName)); } ODataMaterializer.MaterializeDataValues(actualType, entry.Properties, base.ResponseInfo.IgnoreMissingProperties); if (entry.NavigationLinks != null) { foreach (ODataNavigationLink link in entry.NavigationLinks) { ClientPropertyAnnotation annotation2 = actualType.GetProperty(link.Name, true); if (annotation2 != null) { ValidatePropertyMatch(annotation2, link, base.ResponseInfo, true); } } } if (includeLinks && (entry.NavigationLinks != null)) { foreach (ODataNavigationLink link2 in entry.NavigationLinks) { MaterializerNavigationLink link3 = MaterializerNavigationLink.GetLink(link2); if (link3 != null) { ClientPropertyAnnotation annotation3 = actualType.GetProperty(link2.Name, base.ResponseInfo.IgnoreMissingProperties); if (annotation3 != null) { if (link3.Feed != null) { this.ApplyFeedToCollection(entry, annotation3, link3.Feed, includeLinks); } else if (link3.Entry != null) { MaterializerEntry entry2 = link3.Entry; if (entry2.Entry != null) { this.Materialize(entry2, annotation3.PropertyType, includeLinks); } if (entry.ShouldUpdateFromPayload) { annotation3.SetValue(entry.ResolvedObject, entry2.ResolvedObject, link2.Name, true); this.log.SetLink(entry, annotation3.PropertyName, entry2.ResolvedObject); } } } } } } foreach (ODataProperty property in entry.Properties) { if (!(property.Value is ODataStreamReferenceValue)) { ClientPropertyAnnotation annotation4 = actualType.GetProperty(property.Name, base.ResponseInfo.IgnoreMissingProperties); if ((annotation4 != null) && entry.ShouldUpdateFromPayload) { ValidatePropertyMatch(annotation4, property, base.ResponseInfo, true); ODataMaterializer.ApplyDataValue(actualType, property, base.ResponseInfo.IgnoreMissingProperties, base.ResponseInfo, entry.ResolvedObject); } } } ApplyLinkProperties(actualType, entry); if (base.ResponseInfo.HasReadingEntityHandlers) { ODataMaterializer.ReadingEntityInfo annotation = entry.Entry.GetAnnotation <ODataMaterializer.ReadingEntityInfo>(); base.ResponseInfo.FireReadingEntityEvent(entry.ResolvedObject, annotation.EntryPayload, annotation.BaseUri); } }
/// <summary>Materializes the specified <paramref name="entry"/>.</summary> /// <param name="entry">Entry with object to materialize.</param> /// <param name="includeLinks">Whether links that are expanded should be materialized.</param> /// <remarks>This is a payload-driven materialization process.</remarks> private void MaterializeResolvedEntry(MaterializerEntry entry, bool includeLinks) { Debug.Assert(entry.Entry != null, "entry != null"); Debug.Assert(entry.ResolvedObject != null, "entry.ResolvedObject != null -- otherwise not resolved/created!"); ClientTypeAnnotation actualType = entry.ActualType; // While materializing entities, we need to make sure the payload that came in the wire is also an entity. // Otherwise we need to fail. if (!actualType.IsEntityType) { throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidNonEntityType(actualType.ElementTypeName)); } // Note that even if ShouldUpdateFromPayload is false, we will still be creating // nested instances (but not their links), so they show up in the data context // entries. This keeps this code compatible with V1 behavior. this.MaterializeDataValues(actualType, entry.Properties, this.MaterializerContext.IgnoreMissingProperties); if (entry.NavigationLinks != null) { foreach (ODataNavigationLink link in entry.NavigationLinks) { var prop = actualType.GetProperty(link.Name, true); if (prop != null) { ValidatePropertyMatch(prop, link, this.MaterializerContext.Model, true /*performEntityCheck*/); } } if (includeLinks) { foreach (ODataNavigationLink link in entry.NavigationLinks) { MaterializerNavigationLink linkState = MaterializerNavigationLink.GetLink(link); // Ignore... if (linkState == null) { continue; } var prop = actualType.GetProperty(link.Name, this.MaterializerContext.IgnoreMissingProperties); if (prop == null) { continue; } if (linkState.Feed != null) { this.ApplyFeedToCollection(entry, prop, linkState.Feed, includeLinks); } else if (linkState.Entry != null) { MaterializerEntry linkEntry = linkState.Entry; if (linkEntry.Entry != null) { Debug.Assert(includeLinks, "includeLinks -- otherwise we shouldn't be materializing this entry"); this.Materialize(linkEntry, prop.PropertyType, includeLinks); } if (entry.ShouldUpdateFromPayload) { prop.SetValue(entry.ResolvedObject, linkEntry.ResolvedObject, link.Name, true /* allowAdd? */); this.EntityTrackingAdapter.MaterializationLog.SetLink(entry, prop.PropertyName, linkEntry.ResolvedObject); } } } } } foreach (var e in entry.Properties) { if (e.Value is ODataStreamReferenceValue) { continue; } var prop = actualType.GetProperty(e.Name, this.MaterializerContext.IgnoreMissingProperties); if (prop == null) { continue; } if (entry.ShouldUpdateFromPayload) { ValidatePropertyMatch(prop, e, this.MaterializerContext.Model, true /*performEntityCheck*/); this.ApplyDataValue(actualType, e, entry.ResolvedObject); } } // apply link values if present ApplyLinkProperties(actualType, entry); Debug.Assert(entry.ResolvedObject != null, "entry.ResolvedObject != null -- otherwise we didn't do any useful work"); this.MaterializerContext.ResponsePipeline.FireEndEntryEvents(entry); }
public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, MaterializerEntry entry) { MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, entry); link.SetAnnotation<MaterializerNavigationLink>(annotation); return annotation; }
public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, ODataFeed feed) { MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, feed); link.SetAnnotation<MaterializerNavigationLink>(annotation); return annotation; }