/// <summary>Helper method to add a reference property.</summary> /// <param name="resourceType">The resource type to add the property to.</param> /// <param name="name">The name of the property to add.</param> /// <param name="targetResourceSet">The resource set the resource reference property points to.</param> /// <param name="targetResourceType">The resource type the resource set reference property points to.</param> /// <param name="resourceSetReference">true if the property should be a resource set reference, false if it should be resource reference.</param> private void AddReferenceProperty(ResourceType resourceType, string name, ResourceSet targetResourceSet, ResourceType targetResourceType, bool resourceSetReference) { PropertyInfo propertyInfo = resourceType.InstanceType.GetProperty(name); targetResourceType = targetResourceType ?? targetResourceSet.ResourceType; ResourceProperty property = AddResourceProperty( resourceType, name, resourceSetReference ? ResourcePropertyKind.ResourceSetReference : ResourcePropertyKind.ResourceReference, targetResourceType, propertyInfo); // We don't support MEST, that is having two resource sets with the same resource type, so we can determine // the resource set from the resource type. That also means that the property can never point to different resource sets // so we can precreate the ResourceAssociationSet for this property right here as we have all the information. property.GetAnnotation().ResourceAssociationSet = () => { ResourceSet sourceResourceSet = resourceType.GetAnnotation().ResourceSet; ResourceType baseResourceType = resourceType.BaseType; while (sourceResourceSet == null && baseResourceType != null) { sourceResourceSet = baseResourceType.GetAnnotation().ResourceSet; baseResourceType = baseResourceType.BaseType; } return(new ResourceAssociationSet( resourceType.Name + "_" + name + "_" + targetResourceSet.Name, new ResourceAssociationSetEnd(sourceResourceSet, resourceType, property), new ResourceAssociationSetEnd(targetResourceSet, targetResourceType, null))); }; }
/// <summary> /// Delete the given resource /// </summary> /// <param name="targetResource">resource that needs to be deleted</param> /// <remarks>This method gets a "handle" to a resource in the <paramref name="targetResource"/> and should pend a change which /// deletes that resource. /// That includes removing the resource from its resource set and freeing up all the resources associated with that resource. /// Note that this method is not called for complex type instances, only entity resurces are deleted in this way. Complex type instances /// should be deleted when the entity type which points to them is deleted. /// All changes made by this method should be creates as pending until SaveChanges is called which will commit them (or if it's not called and ClearChanges /// is called instead they should be discarded).</remarks> public virtual void DeleteResource(object targetResource) { DSPResource dspTargetResource = ValidateDSPResource(targetResource); ResourceSet resourceSet = null; ResourceType rt = dspTargetResource.ResourceType; while (rt != null) { resourceSet = rt.GetAnnotation().ResourceSet; if (resourceSet != null) { break; } rt = rt.BaseType; } IList <object> resourceSetList = this.dataContext.GetResourceSetEntities(resourceSet.Name); // Add a pending change to remove the resource from the resource set this.pendingChanges.Add(() => { resourceSetList.Remove(dspTargetResource); }); }
/// <summary> /// Returns the EPM annotation for a resource type. /// </summary> /// <param name="resourceType">The resource type to get the EPM annotation for.</param> /// <returns>Returns the EPM annotation for a resource type. If there's no such annotation this returns null.</returns> internal static EpmResourceTypeAnnotation Epm(this ResourceType resourceType) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(resourceType != null, "resourceType != null"); return(resourceType.GetAnnotation <EpmResourceTypeAnnotation>()); }
/// <summary>Adds a resource set to the metadata definition.</summary> /// <param name="name">The name of the resource set to add.</param> /// <param name="entityType">The type of entities in the resource set.</param> /// <returns>The newly created resource set.</returns> public ResourceSet AddResourceSet(string name, ResourceType entityType) { if (entityType.ResourceTypeKind != ResourceTypeKind.EntityType) { throw new ArgumentException("The resource type specified as the base type of a resource set is not an entity type."); } ResourceSet resourceSet = new ResourceSet(name, entityType); entityType.GetAnnotation().ResourceSet = resourceSet; this.resourceSets.Add(name, resourceSet); return(resourceSet); }
private void CreateResourceType(ContentTypeDefinition contentTypeDefinition) { // Try to get the resource type from the dictionary if (this._resourceTypes.ContainsKey(contentTypeDefinition.Name)) { return; } // Create resource type var resourceTypeContentType = new ResourceType( typeof(ContentItem), ResourceTypeKind.EntityType, null, (this as IDataServiceMetadataProvider).ContainerNamespace, contentTypeDefinition.Name, false); resourceTypeContentType.CanReflectOnInstanceType = true; var resourceProperty = new ResourceProperty( "Id", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int))); resourceProperty.CanReflectOnInstanceTypeProperty = true; resourceTypeContentType.AddProperty(resourceProperty); // Add the resource type to the dictionary this._resourceTypes[contentTypeDefinition.Name] = resourceTypeContentType; var contentItem = this._queryEntityService.New(contentTypeDefinition.Name); contentItem.Parts .Join( inner: contentItem.TypeDefinition.Parts, outerKeySelector: contentPart => contentPart.PartDefinition.Name, innerKeySelector: contentypePartDefinition => contentypePartDefinition.PartDefinition.Name, resultSelector: (contentPart, partDefinition) => contentPart) .ToList() .ForEach(contentPart => this.CreateResourceProperty(resourceTypeContentType, contentPart)); // Provide ResourceSet ResourceSet resourceSet = new ResourceSet(resourceTypeContentType.Name + "s", resourceTypeContentType); resourceTypeContentType.GetAnnotation().ResourceSet = resourceSet; // Add annotation to resource set so we can request on this ResourceType resourceSet.CustomState = resourceTypeContentType; this._resourceSets[resourceTypeContentType] = resourceSet; }
/// <summary> /// Gets the property info annotation for the specified resource type or creates a new one if it doesn't exist. /// </summary> /// <param name="resourceType">The resource type to get the annotation for.</param> /// <returns>The property info annotation.</returns> internal static PropertyInfoResourceTypeAnnotation GetPropertyInfoResourceTypeAnnotation(ResourceType resourceType) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(resourceType != null, "resourceType != null"); PropertyInfoResourceTypeAnnotation propertyInfoResourceTypeAnnotation = resourceType.GetAnnotation <PropertyInfoResourceTypeAnnotation>(); if (propertyInfoResourceTypeAnnotation == null) { propertyInfoResourceTypeAnnotation = new PropertyInfoResourceTypeAnnotation(); resourceType.SetAnnotation(propertyInfoResourceTypeAnnotation); } return(propertyInfoResourceTypeAnnotation); }
/// <summary>Helper method to add a reference property.</summary> /// <param name="resourceType">The resource type to add the property to.</param> /// <param name="name">The name of the property to add.</param> /// <param name="targetResourceSet">The resource set the resource reference property points to.</param> /// <param name="resourceSetReference">true if the property should be a resource set reference, false if it should be resource reference.</param> private void AddReferenceProperty(ResourceType resourceType, string name, ResourceSet targetResourceSet, bool resourceSetReference) { ResourceProperty property = new ResourceProperty( name, resourceSetReference ? ResourcePropertyKind.ResourceSetReference : ResourcePropertyKind.ResourceReference, targetResourceSet.ResourceType); property.CanReflectOnInstanceTypeProperty = false; resourceType.AddProperty(property); // We don't support type inheritance so the property can only point to the base resource type of the target resource set // We also don't support MEST, that is having two resource sets with the same resource type, so we can determine // the resource set from the resource type. That also means that the property can never point to different resource sets // so we can precreate the ResourceAssociationSet for this property right here as we have all the information. property.CustomState = new ResourcePropertyAnnotation() { ResourceAssociationSet = new ResourceAssociationSet( resourceType.Name + "_" + name + "_" + targetResourceSet.Name, new ResourceAssociationSetEnd(resourceType.GetAnnotation().ResourceSet, resourceType, property), new ResourceAssociationSetEnd(targetResourceSet, targetResourceSet.ResourceType, null)) }; }