internal void TrackAction(object target, ResourceSetWrapper container, UpdateOperations action) { if (container.ChangeInterceptors != null) { Dictionary<object, UpdateOperations> dictionary; UpdateOperations operations; if (!this.items.TryGetValue(container, out dictionary)) { if (this.service.Provider.IsV1Provider) { dictionary = new Dictionary<object, UpdateOperations>(EqualityComparer<object>.Default); } else { dictionary = new Dictionary<object, UpdateOperations>(ReferenceEqualityComparer<object>.Instance); } this.items.Add(container, dictionary); } if (dictionary.TryGetValue(target, out operations)) { if ((action | operations) != operations) { dictionary[target] = action | operations; } } else { dictionary.Add(target, action); } } }
public void ApplyConfiguration(DataServiceConfiguration configuration, DataServiceProviderWrapper provider) { if (this.Kind == OperationKind.ServiceOperation) { this.serviceOperationRights = configuration.GetServiceOperationRights(this.ServiceOperation); } else { this.serviceActionRights = configuration.GetServiceActionRights(this.ServiceAction); } if (((this.Kind == OperationKind.ServiceOperation) && ((this.serviceOperationRights & ~System.Data.Services.ServiceOperationRights.OverrideEntitySetRights) != System.Data.Services.ServiceOperationRights.None)) || ((this.Kind == OperationKind.Action) && (this.serviceActionRights != System.Data.Services.ServiceActionRights.None))) { if (this.operation.ResourceSet != null) { this.resourceSet = provider.TryResolveResourceSet(this.operation.ResourceSet.Name); if (this.resourceSet == null) { throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_OperationResourceSetNotVisible(this.Name, this.operation.ResourceSet.Name)); } } else if (this.ResultSetPathExpression != null) { this.ResultSetPathExpression.InitializePathSegments(provider); } } }
/// <summary>Fires the notification for a single action.</summary> /// <param name="service">Service on which methods should be invoked.</param> /// <param name="target">Object to be tracked.</param> /// <param name="container">Container in which object is changed.</param> /// <param name="action">Action affecting target.</param> internal static void FireNotification(IDataService service, object target, ResourceSetWrapper container, UpdateOperations action) { Debug.Assert(service != null, "service != null"); AssertActionValues(target, container); MethodInfo[] methods = container.ChangeInterceptors; if (methods != null) { object[] parameters = new object[2]; parameters[0] = target; parameters[1] = action; for (int i = 0; i < methods.Length; i++) { try { methods[i].Invoke(service.Instance, parameters); } catch (TargetInvocationException exception) { ErrorHandler.HandleTargetInvocationException(exception); throw; } } } }
internal void AddEntitySet(string entitySetName, ResourceSetWrapper resourceSet) { IEdmEntityType elementType = (IEdmEntityType) this.model.EnsureSchemaType(resourceSet.ResourceType); IEdmEntitySet target = new EdmEntitySet(this, entitySetName, elementType); MetadataProviderUtils.ConvertCustomAnnotations(this.model, resourceSet.CustomAnnotations, target); this.entitySetCache.Add(entitySetName, target); }
internal IEnumerable <ResourceProperty> GetResourceSerializableProperties(ResourceSetWrapper resourceSet, ResourceType resourceType) { if (resourceType.ResourceTypeKind == ResourceTypeKind.EntityType) { return(resourceSet.GetEntitySerializableProperties(this, resourceType)); } return(resourceType.Properties); }
internal void AddEntitySet(string entitySetName, ResourceSetWrapper resourceSet) { IEdmEntityType elementType = (IEdmEntityType)this.model.EnsureSchemaType(resourceSet.ResourceType); IEdmEntitySet target = new EdmEntitySet(this, entitySetName, elementType); MetadataProviderUtils.ConvertCustomAnnotations(this.model, resourceSet.CustomAnnotations, target); this.entitySetCache.Add(entitySetName, target); }
/// <summary> /// Gets the ResourceAssociationSet instance when given the source association end. /// </summary> /// <param name="resourceSet">Resource set of the source association end.</param> /// <param name="resourceType">Resource type of the source association end.</param> /// <param name="resourceProperty">Resource property of the source association end.</param> /// <returns>ResourceAssociationSet instance.</returns> internal ResourceAssociationSet GetResourceAssociationSet(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(resourceSet != null, "resourceSet != null"); Debug.Assert(resourceType != null, "resourceType != null"); Debug.Assert(resourceProperty != null, "resourceProperty != null"); return(this.metadataProvider.GetResourceAssociationSet(resourceSet.ResourceSet, resourceType, resourceProperty)); }
internal ResourceSetWrapper GetContainer(ResourceSetWrapper sourceContainer, ResourceType sourceResourceType, ResourceProperty navigationProperty) { ResourceAssociationSet set = this.GetResourceAssociationSet(sourceContainer, sourceResourceType, navigationProperty); if (set != null) { ResourceAssociationSetEnd end = set.GetRelatedResourceAssociationSetEnd(sourceContainer, sourceResourceType, navigationProperty); return(this.ValidateResourceSet(end.ResourceSet)); } return(null); }
public ConstantExpression GetQueryRootForResourceSet(ResourceSetWrapper resourceSet, DataServiceOperationContext operationContext) { IQueryable queryRootForResourceSet = this.queryProvider.GetQueryRootForResourceSet(resourceSet.ResourceSet); WebUtil.CheckResourceExists(queryRootForResourceSet != null, resourceSet.Name); if (!resourceSet.QueryRootType.IsAssignableFrom(queryRootForResourceSet.GetType())) { throw new InvalidOperationException(System.Data.Services.Strings.DataServiceProviderWrapper_InvalidQueryRootType(resourceSet.Name, resourceSet.QueryRootType.FullName)); } return(Expression.Constant(queryRootForResourceSet)); }
internal ExpandSegment(string name, Expression filter, int maxResultsExpected, ResourceSetWrapper container, ResourceType targetResourceType, ResourceProperty expandedProperty, System.Data.Services.Providers.OrderingInfo orderingInfo) { WebUtil.CheckArgumentNull<string>(name, "name"); CheckFilterType(filter); this.name = name; this.filter = filter; this.container = container; this.maxResultsExpected = maxResultsExpected; this.expandedProperty = expandedProperty; this.orderingInfo = orderingInfo; this.targetResourceType = targetResourceType; }
/// <summary>Filters a query like a SQL WHERE clause does.</summary> /// <param name="service">Service with data and configuration.</param> /// <param name="setForIt">Set for each item in the query if they are entities</param> /// <param name="typeForIt">Type for each item in the query in Astoria metadata terms</param> /// <param name="source">Original source for query.</param> /// <param name="predicate">Predicate to compose.</param> /// <returns>The composed query.</returns> internal static IQueryable Where(IDataService service, ResourceSetWrapper setForIt, ResourceType typeForIt, IQueryable source, string predicate) { Debug.Assert(service != null, "service != null"); Debug.Assert(typeForIt != null, "typeForIt != null"); Debug.Assert(typeForIt.ResourceTypeKind != ResourceTypeKind.EntityType || setForIt != null, "setForIt cannot be null if typeForIt is an entity type."); Debug.Assert(source != null, "source != null"); Debug.Assert(predicate != null, "predicate != null"); LambdaExpression lambda = ParseLambdaForWhere(service, setForIt, typeForIt, source.ElementType, predicate); return source.Provider.CreateQuery( Expression.Call(typeof(Queryable), "Where", new Type[] { source.ElementType }, source.Expression, Expression.Quote(lambda))); }
internal ResourceSetWrapper GetTargetSet(DataServiceProviderWrapper provider, ResourceSetWrapper bindingSet) { ResourceSetWrapper sourceContainer = bindingSet; for (int i = 0; (sourceContainer != null) && (i < this.pathSegments.Length); i++) { PathSegment segment = this.pathSegments[i]; if (segment.Property != null) { sourceContainer = provider.GetContainer(sourceContainer, segment.SourceType, segment.Property); } } return sourceContainer; }
internal ResourceAssociationSetEnd GetRelatedResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { ResourceAssociationSetEnd end = this.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty); if (end == null) { return null; } if (end != this.End1) { return this.End1; } return this.End2; }
/// <summary> /// Retrieve the related end for the given resource set, type and property. /// </summary> /// <param name="resourceSet">resource set for the source end</param> /// <param name="resourceType">resource type for the source end</param> /// <param name="resourceProperty">resource property for the source end</param> /// <returns>Related resource association set end for the given parameters</returns> internal ResourceAssociationSetEnd GetRelatedResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { Debug.Assert(resourceSet != null, "resourceSet != null"); Debug.Assert(resourceType != null, "resourceType != null"); ResourceAssociationSetEnd thisEnd = this.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty); if (thisEnd != null) { return(thisEnd == this.End1 ? this.End2 : this.End1); } return(null); }
internal ResourceSetWrapper GetTargetSet(DataServiceProviderWrapper provider, ResourceSetWrapper bindingSet) { ResourceSetWrapper sourceContainer = bindingSet; for (int i = 0; (sourceContainer != null) && (i < this.pathSegments.Length); i++) { PathSegment segment = this.pathSegments[i]; if (segment.Property != null) { sourceContainer = provider.GetContainer(sourceContainer, segment.SourceType, segment.Property); } } return(sourceContainer); }
internal ResourceAssociationSetEnd GetRelatedResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { ResourceAssociationSetEnd end = this.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty); if (end == null) { return(null); } if (end != this.End1) { return(this.End1); } return(this.End2); }
internal ResourceSetWrapper ValidateResourceSet(ResourceSet resourceSet) { ResourceSetWrapper wrapper = null; if (resourceSet != null) { if (this.ResourceSetWrapperCache.TryGetValue(resourceSet.Name, out wrapper)) { return(wrapper); } wrapper = ResourceSetWrapper.CreateResourceSetWrapper(resourceSet, this, new Func <ResourceType, ResourceType>(this.ValidateResourceType)); this.ResourceSetWrapperCache[resourceSet.Name] = wrapper; } return(wrapper); }
internal static ResourceSetWrapper CreateResourceSetWrapper(System.Data.Services.Providers.ResourceSet resourceSet, DataServiceProviderWrapper provider, Func <System.Data.Services.Providers.ResourceType, System.Data.Services.Providers.ResourceType> resourceTypeValidator) { if (!resourceSet.IsReadOnly) { throw new DataServiceException(500, System.Data.Services.Strings.DataServiceProviderWrapper_ResourceContainerNotReadonly(resourceSet.Name)); } ResourceSetWrapper wrapper = new ResourceSetWrapper(resourceSet); wrapper.ApplyConfiguration(provider.Configuration); if (!wrapper.IsVisible) { return(null); } wrapper.resourceType = resourceTypeValidator(resourceSet.ResourceType); return(wrapper); }
internal Version GetMinimumResponseVersion(IDataService service, ResourceSetWrapper resourceSet, bool considerEpmInVersion) { Version versionToRaise = WebUtil.RaiseVersion(RequestDescription.Version1Dot0, this.GetMinimumProtocolVersion(considerEpmInVersion)); if (service.Configuration.DataServiceBehavior.ShouldIncludeAssociationLinksInResponse && resourceSet.GetEntitySerializableProperties(service.Provider, this).Any <ResourceProperty>(p => (p.TypeKind == System.Data.Services.Providers.ResourceTypeKind.EntityType))) { versionToRaise = WebUtil.RaiseVersion(versionToRaise, RequestDescription.Version3Dot0); } if (this.IsOpenType) { Version version2 = service.Configuration.DataServiceBehavior.MaxProtocolVersion.ToVersion(); Version requestMaxVersion = service.OperationContext.Host.RequestMaxVersion; Version targetVersion = (requestMaxVersion < version2) ? requestMaxVersion : version2; versionToRaise = WebUtil.RaiseVersion(versionToRaise, targetVersion); } return(versionToRaise); }
internal ResourceAssociationSetEnd GetResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { foreach (ResourceAssociationSetEnd end in new ResourceAssociationSetEnd[] { this.end1, this.end2 }) { if ((end.ResourceSet.Name == resourceSet.Name) && end.ResourceType.IsAssignableFrom(resourceType)) { if ((end.ResourceProperty == null) && (resourceProperty == null)) { return(end); } if (((end.ResourceProperty != null) && (resourceProperty != null)) && (end.ResourceProperty.Name == resourceProperty.Name)) { return(end); } } } return(null); }
internal ResourceAssociationSetEnd GetResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { foreach (ResourceAssociationSetEnd end in new ResourceAssociationSetEnd[] { this.end1, this.end2 }) { if ((end.ResourceSet.Name == resourceSet.Name) && end.ResourceType.IsAssignableFrom(resourceType)) { if ((end.ResourceProperty == null) && (resourceProperty == null)) { return end; } if (((end.ResourceProperty != null) && (resourceProperty != null)) && (end.ResourceProperty.Name == resourceProperty.Name)) { return end; } } } return null; }
/// <summary> /// Creates the wrapper from the given resource set. /// </summary> /// <param name="resourceSet">Resource set instance whose wrapper needs to get created.</param> /// <param name="resourceTypeValidator">Resource type validator.</param> /// <returns>Wrapper for the given resource set.</returns> public static ResourceSetWrapper CreateResourceSetWrapper( ResourceSet resourceSet, Func <ResourceType, ResourceType> resourceTypeValidator) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(resourceSet != null, "resourceSet != null"); Debug.Assert(resourceSet.IsReadOnly, "The resourceSet must be read-only by now."); Debug.Assert(resourceTypeValidator != null, "resourceTypeValidator != null"); ResourceSetWrapper resourceSetWrapper = new ResourceSetWrapper(resourceSet); #if DEBUG resourceSetWrapper.isReadOnly = true; #endif resourceSetWrapper.resourceType = resourceTypeValidator(resourceSet.ResourceType); return(resourceSetWrapper); }
/// <summary> /// Retrieve the end for the given resource set, type and property. /// </summary> /// <param name="resourceSet">resource set for the end</param> /// <param name="resourceType">resource type for the end</param> /// <param name="resourceProperty">resource property for the end</param> /// <returns>Resource association set end for the given parameters</returns> internal ResourceAssociationSetEnd GetResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { Debug.Assert(resourceSet != null, "resourceSet != null"); Debug.Assert(resourceType != null, "resourceType != null"); foreach (ResourceAssociationSetEnd end in new[] { this.end1, this.end2 }) { if (end.ResourceSet.Name == resourceSet.Name && end.ResourceType.IsAssignableFrom(resourceType)) { if ((end.ResourceProperty == null && resourceProperty == null) || (end.ResourceProperty != null && resourceProperty != null && end.ResourceProperty.Name == resourceProperty.Name)) { return(end); } } } return(null); }
internal static void FireNotification(IDataService service, object target, ResourceSetWrapper container, UpdateOperations action) { MethodInfo[] changeInterceptors = container.ChangeInterceptors; if (changeInterceptors != null) { object[] parameters = new object[] { target, action }; for (int i = 0; i < changeInterceptors.Length; i++) { try { changeInterceptors[i].Invoke(service.Instance, parameters); } catch (TargetInvocationException exception) { ErrorHandler.HandleTargetInvocationException(exception); throw; } } } }
private IEnumerable <ResourceType> GetReachableTypesFromSet(ResourceSetWrapper resourceSet, HashSet <ResourceType> visitedTypes) { if (this.HasDerivedTypes(resourceSet.ResourceType)) { foreach (ResourceType iteratorVariable0 in this.GetDerivedTypes(resourceSet.ResourceType)) { foreach (ResourceType iteratorVariable1 in this.GetResourceTypeAndReachableComplexTypes(iteratorVariable0, visitedTypes)) { yield return(iteratorVariable1); } } } for (ResourceType iteratorVariable2 = resourceSet.ResourceType; iteratorVariable2 != null; iteratorVariable2 = iteratorVariable2.BaseType) { foreach (ResourceType iteratorVariable3 in this.GetResourceTypeAndReachableComplexTypes(iteratorVariable2, visitedTypes)) { yield return(iteratorVariable3); } } }
internal ResourceSetWrapper GetResultSet(DataServiceProviderWrapper provider, ResourceSetWrapper bindingSet) { if (this.resourceSet != null) { return this.resourceSet; } if (this.ResultSetPathExpression == null) { return null; } if (bindingSet == null) { throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_PathExpressionRequiresBindingSet(this.Name)); } ResourceSetWrapper targetSet = this.ResultSetPathExpression.GetTargetSet(provider, bindingSet); if (targetSet == null) { throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_TargetSetFromPathExpressionNotNotVisible(this.Name, this.ResultSetPathExpression.PathExpression, bindingSet.Name)); } return targetSet; }
internal ResourceSetWrapper GetResultSet(DataServiceProviderWrapper provider, ResourceSetWrapper bindingSet) { if (this.resourceSet != null) { return(this.resourceSet); } if (this.ResultSetPathExpression == null) { return(null); } if (bindingSet == null) { throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_PathExpressionRequiresBindingSet(this.Name)); } ResourceSetWrapper targetSet = this.ResultSetPathExpression.GetTargetSet(provider, bindingSet); if (targetSet == null) { throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_TargetSetFromPathExpressionNotNotVisible(this.Name, this.ResultSetPathExpression.PathExpression, bindingSet.Name)); } return(targetSet); }
/// <summary> /// Validates that <paramref name="resourceSet"/> is cached and read only. /// </summary> /// <param name="resourceSet">Resource set to be validated.</param> /// <returns>Validated resource set, null if the resource set is not supposed to be visible.</returns> internal ResourceSetWrapper ValidateResourceSet(ResourceSet resourceSet) { DebugUtils.CheckNoExternalCallers(); ResourceSetWrapper resourceSetWrapper = null; if (resourceSet != null) { // For IDSP, we want to make sure the metadata object instance stays the same within // a request because we do reference comparisons. Note the provider can return // different metadata instances within the same request. The Validate*() methods // will make sure to return the first cached instance. if (!this.resourceSetCache.TryGetValue(resourceSet.Name, out resourceSetWrapper)) { ValidateResourceSetReadOnly(resourceSet); resourceSetWrapper = ResourceSetWrapper.CreateResourceSetWrapper(resourceSet, this.ValidateResourceType); this.resourceSetCache[resourceSet.Name] = resourceSetWrapper; } } return(resourceSetWrapper); }
/// <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="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> internal ExpandedProjectionNode( string propertyName, ResourceProperty property, ResourceSetWrapper resourceSetWrapper, OrderingInfo orderingInfo, Expression filter, int?skipCount, int?takeCount, int?maxResultsExpected) : base(propertyName, property) { Debug.Assert(resourceSetWrapper != null, "resourceSetWrapper != null"); Debug.Assert(property != null || propertyName.Length == 0, "We don't support open navigation properties."); this.resourceSetWrapper = resourceSetWrapper; this.orderingInfo = orderingInfo; this.filter = filter; this.skipCount = skipCount; this.takeCount = takeCount; this.maxResultsExpected = maxResultsExpected; this.nodes = new List <ProjectionNode>(); }
public ResourceAssociationSet GetResourceAssociationSet(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { ResourceAssociationSet set; resourceType = GetDeclaringTypeForProperty(resourceType, resourceProperty, null); string key = string.Concat(new object[] { resourceSet.Name, '_', resourceType.FullName, '_', resourceProperty.Name }); if (!this.ResourceAssociationSetCache.TryGetValue(key, out set)) { set = this.metadataProvider.GetResourceAssociationSet(resourceSet.ResourceSet, resourceType, resourceProperty); if (set != null) { ResourceAssociationSetEnd end = set.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty); ResourceAssociationSetEnd end2 = set.GetRelatedResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty); ResourceSetWrapper wrapper = this.ValidateResourceSet(end2.ResourceSet); if (wrapper == null) { set = null; } else { ResourceType type = this.ValidateResourceType(end2.ResourceType); ResourceProperty property = null; if (end2.ResourceProperty != null) { ResourcePropertyKind stream = ResourcePropertyKind.Stream; property = type.TryResolvePropertyName(end2.ResourceProperty.Name, stream); } resourceType = this.ValidateResourceType(end.ResourceType); if ((((end.ResourceSet != resourceSet.ResourceSet) || (end.ResourceType != resourceType)) || ((end.ResourceProperty != resourceProperty) || (end2.ResourceSet != wrapper.ResourceSet))) || ((end2.ResourceType != type) || (end2.ResourceProperty != property))) { set = new ResourceAssociationSet(set.Name, new ResourceAssociationSetEnd(resourceSet.ResourceSet, resourceType, resourceProperty), new ResourceAssociationSetEnd(wrapper.ResourceSet, type, property)); } } } this.ResourceAssociationSetCache.Add(key, set); } return(set); }
/// <summary>Creates new root node for the projection tree.</summary> /// <param name="resourceSetWrapper">The resource set of the root level of the query.</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="expandPaths">The list of expanded paths.</param> /// <param name="baseResourceType">The resource type for all entities in this query.</param> internal RootProjectionNode( ResourceSetWrapper resourceSetWrapper, OrderingInfo orderingInfo, Expression filter, int? skipCount, int? takeCount, int? maxResultsExpected, List<ExpandSegmentCollection> expandPaths, ResourceType baseResourceType) : base( String.Empty, null, resourceSetWrapper, orderingInfo, filter, skipCount, takeCount, maxResultsExpected) { Debug.Assert(baseResourceType != null, "baseResourceType != null"); this.expandPaths = expandPaths; this.baseResourceType = baseResourceType; }
/// <summary>Creates new root node for the projection tree.</summary> /// <param name="resourceSetWrapper">The resource set of the root level of the query.</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="expandPaths">The list of expanded paths.</param> /// <param name="baseResourceType">The resource type for all entities in this query.</param> internal RootProjectionNode( ResourceSetWrapper resourceSetWrapper, OrderingInfo orderingInfo, Expression filter, int?skipCount, int?takeCount, int?maxResultsExpected, List <ExpandSegmentCollection> expandPaths, ResourceType baseResourceType) : base( String.Empty, null, resourceSetWrapper, orderingInfo, filter, skipCount, takeCount, maxResultsExpected) { Debug.Assert(baseResourceType != null, "baseResourceType != null"); this.expandPaths = expandPaths; this.baseResourceType = baseResourceType; }
/// <summary> /// Apply the given configuration to the resource set. /// </summary> /// <param name="configuration">data service configuration instance.</param> /// <param name="provider">data service provider wrapper instance for accessibility validation.</param> public void ApplyConfiguration(DataServiceConfiguration configuration, DataServiceProviderWrapper provider) { #if DEBUG Debug.Assert(!this.isReadOnly, "Can only apply the configuration once."); #endif this.rights = configuration.GetServiceOperationRights(this.serviceOperation); if ((this.rights & ~ServiceOperationRights.OverrideEntitySetRights) != ServiceOperationRights.None) { if (this.serviceOperation.ResourceSet != null) { // If the result type is an entity type, we need to make sure its entity set is visible. // If the entity set is hidden, we need to make sure that we throw an exception. this.resourceSet = provider.TryResolveResourceSet(this.serviceOperation.ResourceSet.Name); if (this.resourceSet == null) { throw new InvalidOperationException(Strings.BaseServiceProvider_ServiceOperationTypeHasNoContainer(this.serviceOperation.Name, this.serviceOperation.ResultType.FullName)); } } } #if DEBUG this.isReadOnly = true; #endif }
private void PairUpNavigationProperty(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty navigationProperty) { string key = string.Concat(new object[] { resourceSet.Name, '_', resourceType.FullName, '_', navigationProperty.Name }); if (!this.associationSetByKeyCache.ContainsKey(key)) { ResourceAssociationSet resourceAssociationSet = this.MetadataProvider.GetResourceAssociationSet(resourceSet, resourceType, navigationProperty); if (resourceAssociationSet != null) { string str2; string str3; ResourceAssociationSetEnd end = resourceAssociationSet.GetRelatedResourceAssociationSetEnd(resourceSet, resourceType, navigationProperty); if (end.ResourceProperty != null) { ResourceAssociationSet set2 = this.MetadataProvider.GetResourceAssociationSet(this.MetadataProvider.ValidateResourceSet(end.ResourceSet), end.ResourceType, end.ResourceProperty); if ((set2 == null) || (resourceAssociationSet.Name != set2.Name)) { throw new InvalidOperationException(System.Data.Services.Strings.ResourceAssociationSet_BidirectionalAssociationMustReturnSameResourceAssociationSetFromBothEnd); } } if (end.ResourceProperty != null) { str2 = string.Concat(new object[] { end.ResourceSet.Name, '_', end.ResourceType.FullName, '_', end.ResourceProperty.Name }); } else { str2 = string.Concat(new object[] { end.ResourceSet.Name, "_Null_", resourceType.FullName, '_', navigationProperty.Name }); } if (this.associationSetByKeyCache.TryGetValue(str2, out str3)) { throw new InvalidOperationException(System.Data.Services.Strings.ResourceAssociationSet_MultipleAssociationSetsForTheSameAssociationTypeMustNotReferToSameEndSets(str3, resourceAssociationSet.Name, end.ResourceSet.Name)); } ResourceAssociationType resourceAssociationType = resourceAssociationSet.ResourceAssociationType; this.PairUpNavigationPropertyWithResourceAssociationSet(entityContainer, resourceAssociationSet, resourceAssociationType, resourceType, navigationProperty); this.associationSetByKeyCache.Add(str2, resourceAssociationSet.Name); this.associationSetByKeyCache.Add(key, resourceAssociationSet.Name); } } }
/// <summary>Parses a lambda expression.</summary> /// <param name="service">Service with data and configuration.</param> /// <param name="setForIt">Resource set for "it" contextual variable.</param> /// <param name="typeForIt">Type for "it" contextual variable.</param> /// <param name="queryElementType">Actual (clr) element type for the sequence</param> /// <param name="expression">Expression to parse.</param> /// <returns>The parsed expression.</returns> private static LambdaExpression ParseLambdaForWhere(IDataService service, ResourceSetWrapper setForIt, ResourceType typeForIt, Type queryElementType, string expression) { Debug.Assert(service != null, "service != null"); Debug.Assert(typeForIt != null, "typeForIt != null"); Debug.Assert(typeForIt.ResourceTypeKind != ResourceTypeKind.EntityType || setForIt != null, "setForIt cannot be null if typeForIt is an entity type."); Debug.Assert(queryElementType != null, "queryElementType != null"); Debug.Assert(expression != null, "expression != null"); Debug.Assert(typeForIt.InstanceType == queryElementType, "typeForIt.InstanceType == queryElementType"); ParameterExpression parameterForIt = Expression.Parameter(queryElementType, "it"); ExpressionParser parser = new ExpressionParser(service, setForIt, typeForIt, parameterForIt, expression); return Expression.Lambda(parser.ParseWhere(), parameterForIt); }
private void PairUpNavigationPropertiesForEntitySet(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet) { foreach (ResourceType type in this.MetadataProvider.GetDerivedTypes(resourceSet.ResourceType)) { this.PairUpNavigationPropertiesForEntitySetAndType(entityContainer, resourceSet, type); } for (ResourceType type2 = resourceSet.ResourceType; type2 != null; type2 = type2.BaseType) { this.PairUpNavigationPropertiesForEntitySetAndType(entityContainer, resourceSet, type2); } }
private void PairUpNavigationPropertiesForEntitySetAndType(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet, ResourceType resourceType) { IEnumerable <ResourceProperty> allVisiblePropertiesDeclaredInThisType = this.GetAllVisiblePropertiesDeclaredInThisType(resourceType); if (allVisiblePropertiesDeclaredInThisType != null) { foreach (ResourceProperty property in from p in allVisiblePropertiesDeclaredInThisType where p.TypeKind == ResourceTypeKind.EntityType select p) { this.PairUpNavigationProperty(entityContainer, resourceSet, resourceType, property); } } }
/// <summary> /// Populate the properties of the given resource /// </summary> /// <param name="jsonObject">JsonObjectRecords containing property name and values</param> /// <param name="resource">instance of the resource whose properties needs to be populated</param> /// <param name="parentResourceSet">resource set where <paramref name="resource"/> belongs to</param> /// <param name="parentResourceType">resource type whose properties needs to be populated</param> /// <returns>true if any properties were set; false otherwise.</returns> private bool PopulateProperties(JsonReader.JsonObjectRecords jsonObject, object resource, ResourceSetWrapper parentResourceSet, ResourceType parentResourceType) { // Update all the properties specified in the payload. // Don't touch the properties which are not specified. Its upto the provider to interpret // the meaning of things which are not specified bool changed = false; List<ResourceProperty> navProperties = new List<ResourceProperty>(); List<object> navPropertyValues = new List<object>(); #region Handle Non-Nav Properties foreach (string propertyName in jsonObject.OrderedKeys) { // Ignore the metadata property if (propertyName == XmlConstants.JsonMetadataString) { continue; } // Check if the property exists and try and set the value ResourceProperty resourceProperty = parentResourceType.TryResolvePropertyName(propertyName); if (resourceProperty == null && parentResourceType.IsOpenType == false) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidPropertyNameSpecified(propertyName, parentResourceType.FullName)); } // Get the property value, set it appropriately, and mark the object as changed. object propertyValue = jsonObject.Entries[propertyName]; bool existingRelationship; // If its a open property if (resourceProperty == null) { this.HandleOpenTypeProperties(resource, propertyName, propertyValue); changed = true; } else if (resourceProperty.TypeKind == ResourceTypeKind.ComplexType) { SegmentInfo segmentInfo = CreateSegment(resourceProperty, resourceProperty.Name, null, true /* singleResult */); segmentInfo.TargetKind = RequestTargetKind.ComplexObject; propertyValue = this.CreateObject(propertyValue, segmentInfo, false /*topLevel*/, out existingRelationship); SetPropertyValue(resourceProperty, resource, propertyValue, ContentFormat.Json, this.Service); changed = true; } else if (resourceProperty.TypeKind == ResourceTypeKind.Primitive) { // Ignoring the value of key properties in PUT payload if (!this.Update || !resourceProperty.IsOfKind(ResourcePropertyKind.Key)) { SetPropertyValue(resourceProperty, resource, propertyValue, ContentFormat.Json, this.Service); } changed = true; } else { Debug.Assert(ResourceTypeKind.EntityType == resourceProperty.TypeKind, "only expecting nav properties"); if (IsDeferredElement(propertyValue)) { // Skip the deferred element continue; } else { navProperties.Add(resourceProperty); navPropertyValues.Add(propertyValue); } } } #endregion Non-Navigation Properties #region Handle Navigation Properties Debug.Assert(navProperties.Count == navPropertyValues.Count, "nav properties and nav property values count must be the same"); // The reason why we need to do this is so that we can gaurantee that the nav properties are getting set at the end. // This is nice, since we already do this in the atom deserializer. Hence its consistent. Second, we wanted to // give a gaurantee that when FK and nav properties are specified in the payload, nav properties always win. for (int i = 0; i < navProperties.Count; i++) { this.HandleNavigationProperty(parentResourceSet, parentResourceType, resource, navProperties[i], navPropertyValues[i]); changed = true; } #endregion Handle Navigation Properties return changed; }
/// <summary> /// Retrieve the related end for the given resource set, type and property. /// </summary> /// <param name="resourceSet">resource set for the source end</param> /// <param name="resourceType">resource type for the source end</param> /// <param name="resourceProperty">resource property for the source end</param> /// <returns>Related resource association set end for the given parameters</returns> internal ResourceAssociationSetEnd GetRelatedResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { Debug.Assert(resourceSet != null, "resourceSet != null"); Debug.Assert(resourceType != null, "resourceType != null"); ResourceAssociationSetEnd thisEnd = this.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty); if (thisEnd != null) { return thisEnd == this.End1 ? this.End2 : this.End1; } return null; }
/// <summary> /// Retrieve the end for the given resource set, type and property. /// </summary> /// <param name="resourceSet">resource set for the end</param> /// <param name="resourceType">resource type for the end</param> /// <param name="resourceProperty">resource property for the end</param> /// <returns>Resource association set end for the given parameters</returns> internal ResourceAssociationSetEnd GetResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { Debug.Assert(resourceSet != null, "resourceSet != null"); Debug.Assert(resourceType != null, "resourceType != null"); foreach (ResourceAssociationSetEnd end in new[] { this.end1, this.end2 }) { if (end.ResourceSet.Name == resourceSet.Name && end.ResourceType.IsAssignableFrom(resourceType)) { if ((end.ResourceProperty == null && resourceProperty == null) || (end.ResourceProperty != null && resourceProperty != null && end.ResourceProperty.Name == resourceProperty.Name)) { return end; } } } return null; }
/// <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="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> internal ExpandedProjectionNode( string propertyName, ResourceProperty property, ResourceSetWrapper resourceSetWrapper, OrderingInfo orderingInfo, Expression filter, int? skipCount, int? takeCount, int? maxResultsExpected) : base(propertyName, property) { Debug.Assert(resourceSetWrapper != null, "resourceSetWrapper != null"); Debug.Assert(property != null || propertyName.Length == 0, "We don't support open navigation properties."); this.resourceSetWrapper = resourceSetWrapper; this.orderingInfo = orderingInfo; this.filter = filter; this.skipCount = skipCount; this.takeCount = takeCount; this.maxResultsExpected = maxResultsExpected; this.nodes = new List<ProjectionNode>(); }
/// <summary> /// Handle the contents under the link element /// </summary> /// <param name="link">syndication link element</param> /// <param name="parentResource">parent resource which contains the link.</param> /// <param name="parentResourceSet">resource set of the parent resource</param> /// <param name="parentResourceType">resource type of the parent resource</param> /// <param name="property">property representing the link.</param> /// <param name="typeParameterValue">type parameter value as specified in the type attribute.</param> /// <param name="propertyName">name of the property that this link represents.</param> /// <returns>returns whether there are child elements under link element.</returns> private LinkContent HandleLinkContent( SyndicationLink link, object parentResource, ResourceSetWrapper parentResourceSet, ResourceType parentResourceType, ResourceProperty property, string typeParameterValue, string propertyName) { Debug.Assert(parentResource != null, "parent resource cannot be null"); Debug.Assert(property != null, "property != null"); Debug.Assert(link != null, "link != null"); LinkContent linkContent = LinkContent.NoInlineElementSpecified; foreach (var e in link.ElementExtensions) { // link can contain other elements apart from the inline elements. if (e.OuterNamespace != XmlConstants.DataWebMetadataNamespace || e.OuterName != XmlConstants.AtomInlineElementName) { continue; } // Deep payload cannot be specified for update if (this.Update) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_DeepUpdateNotSupported); } linkContent = LinkContent.EmptyInlineElementSpecified; using (XmlReader linkReader = e.GetReader()) { while (linkReader.Read()) { if (linkReader.NodeType == XmlNodeType.Element) { string elementName = linkReader.LocalName; string namespaceUri = linkReader.NamespaceURI; if (namespaceUri != XmlConstants.AtomNamespace) { throw DataServiceException.CreateBadRequestError( Strings.BadRequest_InlineElementMustContainValidElement( elementName, XmlConstants.AtomInlineElementName, XmlConstants.AtomFeedElementName, XmlConstants.AtomEntryElementName)); } ResourceSetWrapper targetSet = this.Service.Provider.GetContainer(parentResourceSet, parentResourceType, property); if (targetSet == null) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidPropertyNameSpecified(propertyName, parentResourceType.FullName)); } // FeatureVersion needs to be 2.0 if any of the property in the types contained in the resource set has KeepInContent false this.RequestDescription.UpdateAndCheckEpmFeatureVersion(targetSet, this.Service); linkContent = LinkContent.InlineElementContainsData; if (elementName == XmlConstants.AtomEntryElementName) { if (property.Kind != ResourcePropertyKind.ResourceReference) { throw DataServiceException.CreateBadRequestError(Strings.Syndication_EntryElementForReferenceProperties(e.OuterName, propertyName)); } // Make sure if the media type is specified. If its specified, it should better be link SyndicationItem propertyItem; propertyItem = ReadSyndicationItem(this.factory.CreateSyndicationItemFormatter(), linkReader); SegmentInfo propertySegment = CreateSegment(property, propertyName, targetSet, true /* singleResult */); Debug.Assert(propertySegment.TargetKind != RequestTargetKind.OpenProperty, "Open navigation properties are not supported on OpenTypes."); object propertyValue = this.CreateObject(propertySegment, false /* topLevel */, propertyItem); this.Updatable.SetReference(parentResource, propertyName, propertyValue); } else if (elementName == XmlConstants.AtomFeedElementName) { if (property.Kind != ResourcePropertyKind.ResourceSetReference) { throw DataServiceException.CreateBadRequestError(Strings.Syndication_FeedElementForCollections(e.OuterName, propertyName)); } SyndicationFeed propertyFeed; propertyFeed = ReadSyndicationFeed(this.factory.CreateSyndicationFeedFormatter(), linkReader); SegmentInfo propertySegment = CreateSegment(property, propertyName, targetSet, false /* singleResult */); Debug.Assert(propertySegment.TargetKind != RequestTargetKind.OpenProperty, "Open navigation properties are not supported on OpenTypes."); foreach (SyndicationItem item in propertyFeed.Items) { object propertyValue = this.CreateObject(propertySegment, false /* topLevel */, item); if (propertyValue == null) { if (propertySegment.ProjectedProperty != null && propertySegment.ProjectedProperty.Kind == ResourcePropertyKind.ResourceSetReference) { throw DataServiceException.CreateBadRequestError( Strings.BadRequest_CannotSetCollectionsToNull(propertyName)); } } Debug.Assert( propertySegment.TargetSource == RequestTargetSource.Property && propertySegment.TargetKind == RequestTargetKind.Resource && propertySegment.SingleResult == false, "Must be navigation set property."); this.Updatable.AddReferenceToCollection(parentResource, propertyName, propertyValue); } } else { throw DataServiceException.CreateBadRequestError( Strings.BadRequest_InlineElementMustContainValidElement( elementName, XmlConstants.AtomInlineElementName, XmlConstants.AtomFeedElementName, XmlConstants.AtomEntryElementName)); } } } } } return linkContent; }
/// <summary>Applies the information from a link to the specified resource.</summary> /// <param name='link'>LinkDescriptor with information to apply.</param> /// <param name="resourceSet">Set for the target resource.</param> /// <param name='resourceType'>Type for the target resource.</param> /// <param name='resource'>Target resource to which information will be applied.</param> /// <param name="propertyName">Name of the property that this link represents.</param> private void ApplyLink(SyndicationLink link, ResourceSetWrapper resourceSet, ResourceType resourceType, object resource, string propertyName) { Debug.Assert(link != null, "link != null"); Debug.Assert(resourceType != null, "resourceType != null"); Debug.Assert(resource != null, "resource != null"); ResourceProperty property = resourceType.TryResolvePropertyName(propertyName); if (property == null) { // Open navigation properties are not supported on OpenTypes throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(propertyName)); } if (property.TypeKind != ResourceTypeKind.EntityType) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidNavigationPropertyName(propertyName, resourceType.FullName)); } string typeParameterValue = ValidateTypeParameterForNonOpenTypeProperties(link.MediaType, property); LinkContent linkContent = this.HandleLinkContent(link, resource, resourceSet, resourceType, property, typeParameterValue, propertyName); #region Handle bind/unbind operation // If the href was specified empty or an empty inline element was specified, then we will set the // reference to null - this helps in overrriding if there was a default non-value for this property // else if only link element was specified, and then href points to a single result, then we will // perform a bind operation if ((linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && String.IsNullOrEmpty(link.Uri.OriginalString)) || linkContent == LinkContent.EmptyInlineElementSpecified) { // update the object count when you are performing a bind operation this.CheckAndIncrementObjectCount(); if (property != null && property.Kind == ResourcePropertyKind.ResourceSetReference) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_CannotSetCollectionsToNull(propertyName)); } // For open properties, we will assume that this is a reference property and set it to null this.Updatable.SetReference(resource, propertyName, null); } else if (linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && !String.IsNullOrEmpty(link.Uri.OriginalString)) { // update the object count when you are performing a bind operation this.CheckAndIncrementObjectCount(); // If the link points to a reference navigation property, then update the link Uri referencedUri = RequestUriProcessor.GetAbsoluteUriFromReference(link.Uri.OriginalString, this.Service.OperationContext); RequestDescription description = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service); if (!description.IsSingleResult) { if (property != null && property.Kind == ResourcePropertyKind.ResourceReference) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_LinkHrefMustReferToSingleResource(propertyName)); } return; } // no need to check for null. For collection properties, they can never be null and that // check has been added below. For reference properties, if they are null, it means unbind // and hence no need to check for null. // Get the resource object targetResource = this.Service.GetResource(description, description.SegmentInfos.Length - 1, null); if (property.Kind == ResourcePropertyKind.ResourceReference) { this.Updatable.SetReference(resource, propertyName, targetResource); } else { WebUtil.CheckResourceExists(targetResource != null, description.LastSegmentInfo.Identifier); this.Updatable.AddReferenceToCollection(resource, propertyName, targetResource); } } #endregion Handle bind/unbind operation }
/// <summary> /// Tracks the specified <paramref name="target"/> for a /// given <paramref name="action "/> on the <paramref name="container"/>. /// </summary> /// <param name="target">Object to be tracked.</param> /// <param name="container">Container in which object is changed.</param> /// <param name="action">Action affecting target.</param> /// <remarks> /// If <paramref name="target"/> was already being tracked, the actions are OR'ed together. /// </remarks> internal void TrackAction(object target, ResourceSetWrapper container, UpdateOperations action) { AssertActionValues(target, container); Debug.Assert(this.items != null, "this.items != null - otherwise FireNotification has already been called"); // If it won't be necessary for us to fire authorizatio methods, // skip tracking altogether. if (container.ChangeInterceptors == null) { return; } // Get the container for which the change has taken place. Dictionary<object, UpdateOperations> changedItems; if (!this.items.TryGetValue(container, out changedItems)) { // In order to mantain backwards compatibility, we are going to use default comparer for V1 // providers. However, for V2 providers we are going to do reference equality comparisons. if (this.service.Provider.IsV1Provider) { changedItems = new Dictionary<object, UpdateOperations>(EqualityComparer<object>.Default); } else { changedItems = new Dictionary<object, UpdateOperations>(ReferenceEqualityComparer<object>.Instance); } this.items.Add(container, changedItems); } UpdateOperations existingAction; if (changedItems.TryGetValue(target, out existingAction)) { if ((action | existingAction) != existingAction) { changedItems[target] = action | existingAction; } } else { changedItems.Add(target, action); } }
internal RootProjectionNode(ResourceSetWrapper resourceSetWrapper, OrderingInfo orderingInfo, Expression filter, int? skipCount, int? takeCount, int? maxResultsExpected, List<ExpandSegmentCollection> expandPaths, System.Data.Services.Providers.ResourceType baseResourceType) : base(string.Empty, null, null, resourceSetWrapper, orderingInfo, filter, skipCount, takeCount, maxResultsExpected) { this.expandPaths = expandPaths; this.baseResourceType = baseResourceType; }
internal void SetETagValues(object resourceCookie, ResourceSetWrapper container) { DataServiceHostWrapper host = this.service.OperationContext.Host; object obj2 = this.ResolveResource(resourceCookie); ResourceType nonPrimitiveResourceType = WebUtil.GetNonPrimitiveResourceType(this.service.Provider, obj2); IList<ResourceProperty> eTagProperties = this.service.Provider.GetETagProperties(container.Name, nonPrimitiveResourceType); if (eTagProperties.Count == 0) { if (!string.IsNullOrEmpty(host.RequestIfMatch)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.Serializer_NoETagPropertiesForType); } } else { IDataServiceUpdateProvider updateProvider = this.updateProvider as IDataServiceUpdateProvider; if (updateProvider != null) { IEnumerable<KeyValuePair<string, object>> emptyKeyValuePairStringObject; bool? checkForEquality = null; if (!string.IsNullOrEmpty(host.RequestIfMatch)) { checkForEquality = true; emptyKeyValuePairStringObject = ParseETagValue(eTagProperties, host.RequestIfMatch); } else { emptyKeyValuePairStringObject = WebUtil.EmptyKeyValuePairStringObject; } updateProvider.SetConcurrencyValues(resourceCookie, checkForEquality, emptyKeyValuePairStringObject); } else { if (string.IsNullOrEmpty(host.RequestIfMatch)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.DataService_CannotPerformOperationWithoutETag(nonPrimitiveResourceType.FullName)); } if ((host.RequestIfMatch != "*") && (WebUtil.GetETagValue(resourceCookie, nonPrimitiveResourceType, eTagProperties, this.service, false) != host.RequestIfMatch)) { throw DataServiceException.CreatePreConditionFailedError(System.Data.Services.Strings.Serializer_ETagValueDoesNotMatch); } } } }
/// <summary>Initializes a new <see cref="ExpressionParser"/>.</summary> /// <param name="service">Service with data and configuration.</param> /// <param name="setForIt">Resource set for "it" contextual variable</param> /// <param name="typeForIt">Type for "it" contextual variable</param> /// <param name="parameterForIt">Parameters for the current "it" context.</param> /// <param name="expression">Expression to parse.</param> internal ExpressionParser(IDataService service, ResourceSetWrapper setForIt, ResourceType typeForIt, ParameterExpression parameterForIt, string expression) { Debug.Assert(service != null, "service != null"); // For Open types, we could potentially have typeForIt parameter set to null value, // However, we have decided not support ordering on Open properties which also implies // that we can not have entity typed properties on Open types Debug.Assert(typeForIt != null, "typeForIt != null"); Debug.Assert(expression != null, "expression != null"); Debug.Assert(parameterForIt != null, "parameterForIt != null"); this.service = service; this.provider = service.Provider; this.nullPropagationRequired = this.provider.NullPropagationRequired; this.literals = new Dictionary<Expression, string>(ReferenceEqualityComparer<Expression>.Instance); this.setForIt = setForIt; this.typeForIt = typeForIt; this.it = parameterForIt; this.lexer = new ExpressionLexer(expression); }
/// <summary> /// Handle the navigation properties as specified in the payload /// </summary> /// <param name="parentResourceSet">resource set where <paramref name="resource"/> belongs to</param> /// <param name="parentResourceType">resource type declaring the navigation property.</param> /// <param name="resource">instance of the resource declaring the navigation property.</param> /// <param name="resourceProperty">resource property containing metadata about the navigation property.</param> /// <param name="propertyValue">value of the navigation property.</param> private void HandleNavigationProperty(ResourceSetWrapper parentResourceSet, ResourceType parentResourceType, object resource, ResourceProperty resourceProperty, object propertyValue) { Debug.Assert(parentResourceSet != null, "parentResourceSet != null"); Debug.Assert(parentResourceType != null, "parentResourceType != null"); Debug.Assert(resourceProperty != null && resourceProperty.TypeKind == ResourceTypeKind.EntityType, "its must be a nav property"); bool existingRelationship; Deserializer.CheckForBindingInPutOperations(this.Service.OperationContext.Host.AstoriaHttpVerb); ResourceSetWrapper propertySet = this.Service.Provider.GetContainer(parentResourceSet, parentResourceType, resourceProperty); if (propertySet == null) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidPropertyNameSpecified(resourceProperty.Name, parentResourceType.FullName)); } // FeatureVersion needs to be 2.0 if any of the property in the types contained in the resource set has KeepInContent false this.RequestDescription.UpdateAndCheckEpmFeatureVersion(propertySet, this.Service); if (resourceProperty.Kind == ResourcePropertyKind.ResourceReference) { SegmentInfo segmentInfo = CreateSegment(resourceProperty, resourceProperty.Name, propertySet, true /* singleResult */); segmentInfo.TargetKind = RequestTargetKind.Resource; // For navigation property, allow both inserts and binding in this case propertyValue = this.CreateObject(propertyValue, segmentInfo, false /*topLevel*/, out existingRelationship); if (!existingRelationship) { this.Updatable.SetReference(resource, resourceProperty.Name, propertyValue); } } else if (resourceProperty.Kind == ResourcePropertyKind.ResourceSetReference) { if (propertyValue == null) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_CannotSetCollectionsToNull(resourceProperty.Name)); } ArrayList resourceCollection = GetArrayList(propertyValue); SegmentInfo segmentInfo = CreateSegment(resourceProperty, resourceProperty.Name, propertySet, true /* singleResult */); foreach (object resourceObject in resourceCollection) { object resourceInstance = this.CreateObject(resourceObject, segmentInfo, false /*topLevel*/, out existingRelationship); Debug.Assert(resourceInstance != null, "resourceInstance != null"); if (!existingRelationship) { this.Updatable.AddReferenceToCollection(resource, resourceProperty.Name, resourceInstance); } } } }
/// <summary>Constructor.</summary> /// <param name="resourceType">Type for current segment.</param> /// <param name="resourceSet">Set for current segment.</param> /// <param name="isCollection">Does current segment property refer to a collection.</param> public SegmentTypeInfo(ResourceType resourceType, ResourceSetWrapper resourceSet, bool isCollection) { this.ResourceType = resourceType; this.ResourceSet = resourceSet; this.IsCollection = isCollection; }
private void PairUpNavigationPropertiesForEntitySetAndType(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet, ResourceType resourceType) { IEnumerable<ResourceProperty> allVisiblePropertiesDeclaredInThisType = this.GetAllVisiblePropertiesDeclaredInThisType(resourceType); if (allVisiblePropertiesDeclaredInThisType != null) { foreach (ResourceProperty property in from p in allVisiblePropertiesDeclaredInThisType where p.TypeKind == ResourceTypeKind.EntityType select p) { this.PairUpNavigationProperty(entityContainer, resourceSet, resourceType, property); } } }
private static void AssertActionValues(object target, ResourceSetWrapper container) { Debug.Assert(target != null, "target != null"); Debug.Assert(container != null, "container != null"); }
/// <summary>Initializes a new <see cref="ExpandSegment"/> instance.</summary> /// <param name="name">Segment name.</param> /// <param name="filter">Filter expression for segment, possibly null.</param> /// <param name="maxResultsExpected"> /// Expand providers may choose to return at most MaxResultsExpected + 1 elements to allow the /// data service to detect a failure to meet this constraint. /// </param> /// <param name="container">Container to which the segment belongs; possibly null.</param> /// <param name="expandedProperty">Property expanded by this expand segment</param> /// <param name="orderingInfo">Collection of ordering information for this segment, used for paging</param> internal ExpandSegment( string name, Expression filter, int maxResultsExpected, ResourceSetWrapper container, ResourceProperty expandedProperty, OrderingInfo orderingInfo) { WebUtil.CheckArgumentNull(name, "name"); CheckFilterType(filter); this.name = name; this.filter = filter; this.container = container; this.maxResultsExpected = maxResultsExpected; this.expandedProperty = expandedProperty; this.orderingInfo = orderingInfo; }
internal RootProjectionNode(ResourceSetWrapper resourceSetWrapper, OrderingInfo orderingInfo, Expression filter, int?skipCount, int?takeCount, int?maxResultsExpected, List <ExpandSegmentCollection> expandPaths, System.Data.Services.Providers.ResourceType baseResourceType) : base(string.Empty, null, null, resourceSetWrapper, orderingInfo, filter, skipCount, takeCount, maxResultsExpected) { this.expandPaths = expandPaths; this.baseResourceType = baseResourceType; }