/// <summary>Creates a new instance of the <see cref="T:Microsoft.OData.Service.Providers.ResourceAssociationSetEnd" /> class.</summary> /// <param name="resourceSet">The resource set to which the <see cref="T:Microsoft.OData.Service.Providers.ResourceAssociationSetEnd" /> end belongs.</param> /// <param name="resourceType">The resource type to which the <see cref="T:Microsoft.OData.Service.Providers.ResourceAssociationSetEnd" /> end belongs.</param> /// <param name="resourceProperty">The resource property that returns the <see cref="T:Microsoft.OData.Service.Providers.ResourceAssociationSetEnd" /> end.</param> public ResourceAssociationSetEnd(ResourceSet resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { WebUtil.CheckArgumentNull(resourceSet, "resourceSet"); WebUtil.CheckArgumentNull(resourceType, "resourceType"); if (resourceProperty != null && (resourceType.TryResolvePropertyName(resourceProperty.Name) == null || resourceProperty.TypeKind != ResourceTypeKind.EntityType)) { throw new ArgumentException(Strings.ResourceAssociationSetEnd_ResourcePropertyMustBeNavigationPropertyOnResourceType); } if (!resourceSet.ResourceType.IsAssignableFrom(resourceType) && !resourceType.IsAssignableFrom(resourceSet.ResourceType)) { throw new ArgumentException(Strings.ResourceAssociationSetEnd_ResourceTypeMustBeAssignableToResourceSet); } this.resourceSet = resourceSet; this.resourceType = resourceType; // Note that for the TargetEnd, resourceProperty can be null. this.resourceProperty = resourceProperty; }
/// <summary>Creates new instance of <see cref="ProjectionNode"/> which represents a simple projected property.</summary> /// <param name="propertyName">The name of the property to project.</param> /// <param name="property">The <see cref="ResourceProperty"/> for the property to project. If an open property /// is to be projected, specify null.</param> /// <param name="targetResourceType">The resource type for which the <see cref="property"/>needs to be projected.</param> internal ProjectionNode(string propertyName, ResourceProperty property, ResourceType targetResourceType) { Debug.Assert(propertyName != null, "propertyName != null"); Debug.Assert(property == null || property.Name == propertyName, "If the property is specified its name must match."); #if DEBUG // For rootProjectionNode, there is no targetResourceType. Hence checking for propertyName to be String.Empty to excluse RootProjectionNode from the assert. if (!String.IsNullOrEmpty(propertyName)) { Debug.Assert(targetResourceType != null, "targetResourceType != null"); if (property != null) { Debug.Assert(object.ReferenceEquals(targetResourceType.TryResolvePropertyName(propertyName), property), "object.ReferenceEquals(targetResourceType.TryResolvePropertyName(propertyName), property)"); } else { Debug.Assert(targetResourceType.IsOpenType, "targetResourceType.IsOpenType"); } } #endif this.propertyName = propertyName; this.property = property; this.targetResourceType = targetResourceType; }
/// <summary>Applies a property from the reader to the specified resource.</summary> /// <param name='property'>The OData property to apply.</param> /// <param name='resourceType'>Type of resource.</param> /// <param name='resource'>Resource to set value on.</param> protected void ApplyProperty(ODataProperty property, ResourceType resourceType, object resource) { Debug.Assert(property != null, "property != null"); Debug.Assert(resourceType != null, "resourceType != null"); Debug.Assert(resource != null, "resource != null"); string propertyName = property.Name; // Note that we include even stream properties in this lookup // This is not needed for the purposes of validation, since that has already been done by ODataLib reader. ResourceProperty resourceProperty = resourceType.TryResolvePropertyName(propertyName); ResourceType propertyResourceType; if (resourceProperty == null) { Debug.Assert(resourceType.IsOpenType, "ODataLib reader should have already failed on undefined properties on non-open types."); propertyResourceType = null; } else if (resourceProperty.Kind == ResourcePropertyKind.Stream) { // Ignore stream properties in update operations. return; } else { // Ignore key properties. if (this.Update && resourceProperty.IsOfKind(ResourcePropertyKind.Key)) { return; } propertyResourceType = resourceProperty.ResourceType; } object propertyValue = this.ConvertValue(property.Value, ref propertyResourceType); if (resourceProperty == null) { Deserializer.SetOpenPropertyValue(resource, propertyName, propertyValue, this.Service); } else { Deserializer.SetPropertyValue(resourceProperty, resource, propertyValue, this.Service); } return; }
/// <summary>Creates new instance of node representing expanded navigation property.</summary> /// <param name="propertyName">The name of the property to project and expand.</param> /// <param name="property">The <see cref="ResourceProperty"/> for this property. Can only be null for the root node.</param> /// <param name="targetResourceType">Target resource type on which the expansion needs to happen.</param> /// <param name="resourceSetWrapper">The resource set to which the expansion leads.</param> /// <param name="orderingInfo">The ordering info for this node. null means no ordering to be applied.</param> /// <param name="filter">The filter for this node. null means no filter to be applied.</param> /// <param name="skipCount">Number of results to skip. null means no results to be skipped.</param> /// <param name="takeCount">Maximum number of results to return. null means return all available results.</param> /// <param name="maxResultsExpected">Maximum number of expected results. Hint that the provider should return /// at least maxResultsExpected + 1 results (if available).</param> /// <param name="selectExpandClause">The select expand clause for the current node from the URI Parser.</param> internal ExpandedProjectionNode( string propertyName, ResourceProperty property, ResourceType targetResourceType, ResourceSetWrapper resourceSetWrapper, OrderingInfo orderingInfo, Expression filter, int? skipCount, int? takeCount, int? maxResultsExpected, SelectExpandClause selectExpandClause) : base(propertyName, property, targetResourceType) { Debug.Assert(resourceSetWrapper != null, "resourceSetWrapper != null"); Debug.Assert(property != null || (propertyName.Length == 0 && targetResourceType == null), "We don't support open navigation properties."); Debug.Assert(property == null || targetResourceType.TryResolvePropertyName(property.Name) != null, "Property must exist on the target resource type"); Debug.Assert(selectExpandClause != null, "selectExpandClause != null"); this.resourceSetWrapper = resourceSetWrapper; this.orderingInfo = orderingInfo; this.filter = filter; this.skipCount = skipCount; this.takeCount = takeCount; this.maxResultsExpected = maxResultsExpected; this.nodes = new List<ProjectionNode>(); this.hasExpandedPropertyOnDerivedType = false; this.selectExpandClause = selectExpandClause; }
/// <summary> /// Get the list of etag property names given the entity set name and the instance of the resource /// </summary> /// <param name="containerName">name of the entity set</param> /// <param name="resourceType">Type of the resource whose etag properties need to be fetched</param> /// <returns>list of etag property names</returns> public virtual IList<ResourceProperty> GetETagProperties(string containerName, ResourceType resourceType) { WebUtil.CheckStringArgumentNullOrEmpty(containerName, "containerName"); WebUtil.CheckArgumentNull(resourceType, "resourceType"); EntitySetBase entitySet = this.GetEntitySet(containerName); EntityType entityType = this.ObjectContext.MetadataWorkspace.GetItem<EntityType>(resourceType.FullName, DataSpace.CSpace); Debug.Assert(entityType != null, "entityType != null"); List<ResourceProperty> etagProperties = new List<ResourceProperty>(); // Workspace associated directly with the ObjectContext has metadata only about OSpace, CSpace and OCSpace. // Since GetRequiredOriginalValueMembers depends on mapping information (CSSpace metadata), // we need to make sure we call this API on a workspace which has information about the CS Mapping. // Hence getting workspace from the underlying Entity connection. MetadataWorkspace workspace = ((EntityConnection)this.ObjectContext.Connection).GetMetadataWorkspace(); #if EF6Provider foreach (EdmMember member in workspace.GetRelevantMembersForUpdate(entitySet, entityType, true /*partialUpdateSupported*/)) #else foreach (EdmMember member in workspace.GetRequiredOriginalValueMembers(entitySet, entityType)) #endif { ResourceProperty property = resourceType.TryResolvePropertyName(member.Name, exceptKind: ResourcePropertyKind.Stream); Debug.Assert(property != null, "property != null"); Debug.Assert(property.ResourceType.ResourceTypeKind == ResourceTypeKind.Primitive, "property.ResourceType.TypeKind == ResourceTypeKind.Primitive"); // Ignore key properties if they are part of etag, since the uri already has the key information // and it makes no sense to duplicate them in etag if (!property.IsOfKind(ResourcePropertyKind.Key)) { etagProperties.Add(property); } } return etagProperties; }