private ResourcePropertyInfo GetResourcePropertyInfo(ResourceProperty resourceProperty) { ResourcePropertyInfo propertyInfoDecaredOnThisType = null; for (ResourceType type = this; (propertyInfoDecaredOnThisType == null) && (type != null); type = type.BaseType) { propertyInfoDecaredOnThisType = type.GetPropertyInfoDecaredOnThisType(resourceProperty); } return(propertyInfoDecaredOnThisType); }
protected ResourcePropertyInfo GetNavigationPropertyInfo(IExpandedResult expanded, object customObject, ResourceType currentResourceType, ResourceProperty property) { ExpandedProjectionNode node; object obj2 = null; bool expand = this.ShouldExpandSegment(property, currentResourceType, out node); if (expand) { obj2 = this.GetExpandedProperty(expanded, customObject, property, node); } return(ResourcePropertyInfo.CreateResourcePropertyInfo(property, obj2, node, expand)); }
private ResourcePropertyInfo GetPropertyInfoDecaredOnThisType(ResourceProperty resourceProperty) { ResourcePropertyInfo info; if (this.propertyInfosDeclaredOnThisType == null) { this.propertyInfosDeclaredOnThisType = new Dictionary <ResourceProperty, ResourcePropertyInfo>(ReferenceEqualityComparer <ResourceProperty> .Instance); } if (!this.propertyInfosDeclaredOnThisType.TryGetValue(resourceProperty, out info)) { PropertyInfo property = this.InstanceType.GetProperty(resourceProperty.Name, BindingFlags.Public | BindingFlags.Instance); if (property == null) { throw new DataServiceException(500, System.Data.Services.Strings.BadProvider_UnableToGetPropertyInfo(this.FullName, resourceProperty.Name)); } info = new ResourcePropertyInfo(property); this.propertyInfosDeclaredOnThisType.Add(resourceProperty, info); } return(info); }
private void WriteNavigationProperties(IExpandedResult expanded, EntityToSerialize entityToSerialize, bool resourceInstanceInFeed, IEnumerable <ProjectionNode> projectionNodesForCurrentResourceType) { Debug.Assert(entityToSerialize != null, "entityToSerialize != null"); Debug.Assert( projectionNodesForCurrentResourceType == null || projectionNodesForCurrentResourceType.All(projectionNode => projectionNode.TargetResourceType.IsAssignableFrom(entityToSerialize.ResourceType)), "The projection nodes must be filtered to the current resource type only."); IEnumerable <ResourceProperty> navProperties = projectionNodesForCurrentResourceType == null ? this.Provider.GetResourceSerializableProperties(this.CurrentContainer, entityToSerialize.ResourceType).Where(p => p.TypeKind == ResourceTypeKind.EntityType) : projectionNodesForCurrentResourceType.Where(p => p.Property != null && p.Property.TypeKind == ResourceTypeKind.EntityType).Select(p1 => p1.Property); foreach (ResourceProperty property in navProperties) { ResourcePropertyInfo navProperty = this.GetNavigationPropertyInfo(expanded, entityToSerialize.Entity, entityToSerialize.ResourceType, property); ODataNavigationLink navLink = this.GetNavigationLink(entityToSerialize, navProperty.Property); // WCF Data Services show performance degradation with JsonLight when entities have > 25 Navgations on writing entries // DEVNOTE: for performance reasons, if the link has no content due to the metadata level, and is not expanded // then don't tell ODataLib about it at all. if (navLink.Url == null && navLink.AssociationLinkUrl == null && !navProperty.Expand) { continue; } var linkArgs = new DataServiceODataWriterNavigationLinkArgs(navLink, this.Service.OperationContext); this.dataServicesODataWriter.WriteStart(linkArgs); if (navProperty.Expand) { object navPropertyValue = navProperty.Value; IExpandedResult navPropertyExpandedResult = navPropertyValue as IExpandedResult; object expandedPropertyValue = navPropertyExpandedResult != null? GetExpandedElement(navPropertyExpandedResult) : navPropertyValue; bool needPop = this.PushSegmentForProperty(navProperty.Property, entityToSerialize.ResourceType, navProperty.ExpandedNode); // if this.CurrentContainer is null, the target set of the navigation property is hidden. if (this.CurrentContainer != null) { if (navProperty.Property.Kind == ResourcePropertyKind.ResourceSetReference) { IEnumerable enumerable; bool collection = WebUtil.IsElementIEnumerable(expandedPropertyValue, out enumerable); Debug.Assert(collection, "metadata loading must have ensured that navigation set properties must implement IEnumerable"); QueryResultInfo queryResults = new QueryResultInfo(enumerable); try { queryResults.MoveNext(); Func <Uri> getNavPropertyRelativeUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, navLink.Name); Func <Uri> getNavPropertyAbsoluteUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.AbsoluteEditLink, navLink.Name); this.WriteFeedElements(navPropertyExpandedResult, queryResults, navProperty.Property.ResourceType, navLink.Name, getNavPropertyRelativeUri, getNavPropertyAbsoluteUri, false); } finally { // After the navigation property is completely serialized, dispose the property value. WebUtil.Dispose(queryResults); } } else if (WebUtil.IsNullValue(expandedPropertyValue)) { // Write a null reference navigation property var entryArgs = new DataServiceODataWriterEntryArgs(null, null, this.Service.OperationContext); this.dataServicesODataWriter.WriteStart(entryArgs); this.dataServicesODataWriter.WriteEnd(entryArgs); } else { this.WriteEntry(navPropertyExpandedResult, expandedPropertyValue, resourceInstanceInFeed, navProperty.Property.ResourceType); } } this.PopSegmentName(needPop); } this.dataServicesODataWriter.WriteEnd(linkArgs); // end of navigation property } }
private ResourcePropertyInfo GetPropertyInfoDecaredOnThisType(ResourceProperty resourceProperty) { ResourcePropertyInfo info; if (this.propertyInfosDeclaredOnThisType == null) { this.propertyInfosDeclaredOnThisType = new Dictionary<ResourceProperty, ResourcePropertyInfo>(ReferenceEqualityComparer<ResourceProperty>.Instance); } if (!this.propertyInfosDeclaredOnThisType.TryGetValue(resourceProperty, out info)) { PropertyInfo property = this.InstanceType.GetProperty(resourceProperty.Name, BindingFlags.Public | BindingFlags.Instance); if (property == null) { throw new DataServiceException(500, System.Data.Services.Strings.BadProvider_UnableToGetPropertyInfo(this.FullName, resourceProperty.Name)); } info = new ResourcePropertyInfo(property); this.propertyInfosDeclaredOnThisType.Add(resourceProperty, info); } return info; }
/// <summary> /// Adds A resourcepropertyInfo instance to the internal propertyInfosDeclaredOnThisType dictionary. /// </summary> /// <param name="resourceProperty">The resource property to add to the dictionary</param> /// <param name="propertyInfo">The propertyInfo handle to the instance property represented by the <paramref name="resourceProperty"/> </param> /// <returns>A resourcepropertyInfo instance that allows access to the instance property</returns> private ResourcePropertyInfo AddPropertyToResourceTypePropertyInfoCache(ResourceProperty resourceProperty, PropertyInfo propertyInfo) { ResourcePropertyInfo resourcePropertyInfo = new ResourcePropertyInfo(propertyInfo); var propertiesDictionary = new Dictionary<ResourceProperty, ResourcePropertyInfo>(this.propertyInfosDeclaredOnThisType, ReferenceEqualityComparer<ResourceProperty>.Instance); propertiesDictionary.Add(resourceProperty, resourcePropertyInfo); Interlocked.Exchange(ref this.propertyInfosDeclaredOnThisType, propertiesDictionary); return resourcePropertyInfo; }