public StarshipOfficersRelatedResourceMaterializer(ResourceTypeRelationship relationship, DbContext dbContext,
                                                    IQueryableResourceCollectionDocumentBuilder queryableResourceCollectionDocumentBuilder,
                                                    ISortExpressionExtractor sortExpressionExtractor,
                                                    IResourceTypeRegistration primaryTypeRegistration)
     : base(relationship, dbContext, queryableResourceCollectionDocumentBuilder, sortExpressionExtractor, primaryTypeRegistration)
 {
     _dbContext = dbContext;
 }
Esempio n. 2
0
 public StarshipShipCounselorRelatedResourceMaterializer(
     ISingleResourceDocumentBuilder singleResourceDocumentBuilder, IBaseUrlService baseUrlService,
     IResourceTypeRegistration primaryTypeRegistration, ResourceTypeRelationship relationship,
     DbContext dbContext)
     : base(singleResourceDocumentBuilder, baseUrlService, primaryTypeRegistration, relationship, dbContext)
 {
     _dbContext = dbContext;
 }
 /// <summary>
 /// Builds a new EntityFrameworkToOneRelatedResourceDocumentMaterializer
 /// </summary>
 public EntityFrameworkToOneRelatedResourceDocumentMaterializer(
     ISingleResourceDocumentBuilder singleResourceDocumentBuilder, IBaseUrlService baseUrlService,
     IResourceTypeRegistration primaryTypeRegistration, ResourceTypeRelationship relationship,
     DbContext dbContext)
     : base(singleResourceDocumentBuilder, baseUrlService)
 {
     _primaryTypeRegistration = primaryTypeRegistration;
     _relationship            = relationship;
     _dbContext = dbContext;
 }
 /// <summary>
 /// Builds a new EntityFrameworkToManyRelatedResourceDocumentMaterializer.
 /// </summary>
 public EntityFrameworkToManyRelatedResourceDocumentMaterializer(
     ResourceTypeRelationship relationship,
     DbContext dbContext,
     IQueryableResourceCollectionDocumentBuilder queryableResourceCollectionDocumentBuilder,
     ISortExpressionExtractor sortExpressionExtractor,
     IResourceTypeRegistration primaryTypeRegistration)
     : base(queryableResourceCollectionDocumentBuilder, sortExpressionExtractor)
 {
     _relationship            = relationship;
     _dbContext               = dbContext;
     _primaryTypeRegistration = primaryTypeRegistration;
 }
        /// <summary>
        /// Constructs a URL for the resource(s) on the other side of the given relationship, belonging to the given resource
        /// </summary>
        /// <param name="relationshipOwner"></param>
        /// <param name="resourceTypeRegistry"></param>
        /// <param name="property"></param>
        /// <param name="baseUrl"></param>
        /// <returns></returns>
        protected virtual string BuildRelatedResourceUrl(object relationshipOwner, IResourceTypeRegistry resourceTypeRegistry,
                                                         ResourceTypeRelationship property, string baseUrl)
        {
            var relationshipOwnerType = relationshipOwner.GetType();
            var sanitizedBaseUrl      = GetSanitizedBaseUrl(baseUrl);
            var registration          = resourceTypeRegistry.GetRegistrationForType(relationshipOwnerType);
            var id = registration.GetIdForResource(relationshipOwner);

            if (property.RelatedResourceLinkTemplate != null)
            {
                var replacedString = property.RelatedResourceLinkTemplate.Replace("{1}", id);
                return(String.Format("{0}/{1}", sanitizedBaseUrl, replacedString));
            }

            return(String.Format("{0}/{1}/{2}/{3}", sanitizedBaseUrl, registration.ResourceTypeName, id, property.JsonKey));
        }
Esempio n. 6
0
        /// <summary>
        /// Generic method for getting the related resources for a to-one relationship
        /// </summary>
        protected async Task <ISingleResourceDocument> GetRelatedToOne <TRelated>(string id,
                                                                                  ResourceTypeRelationship relationship, HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var param        = Expression.Parameter(typeof(T));
            var accessorExpr = Expression.Property(param, relationship.Property);
            var lambda       = Expression.Lambda <Func <T, TRelated> >(accessorExpr, param);

            var primaryEntityQuery  = FilterById <T>(id, _resourceTypeRegistration);
            var primaryEntityExists = await primaryEntityQuery.AnyAsync(cancellationToken);

            if (!primaryEntityExists)
            {
                throw JsonApiException.CreateForNotFound(string.Format("No resource of type `{0}` exists with id `{1}`.",
                                                                       _resourceTypeRegistration.ResourceTypeName, id));
            }
            var relatedResource = await primaryEntityQuery.Select(lambda).FirstOrDefaultAsync(cancellationToken);

            return(_singleResourceDocumentBuilder.BuildDocument(relatedResource, GetBaseUrlFromRequest(request), null, null));
        }
        private Expression GetPredicateBodyForRelationship(ResourceTypeRelationship resourceTypeProperty, string queryValue, ParameterExpression param)
        {
            var          relatedType = resourceTypeProperty.RelatedType;
            PropertyInfo relatedIdProperty;

            try
            {
                var registration = _resourceTypeRegistry.GetRegistrationForType(relatedType);
                relatedIdProperty = registration.IdProperty;
            }
            catch (TypeRegistrationNotFoundException)
            {
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }

            var prop = resourceTypeProperty.Property;

            if (resourceTypeProperty.IsToMany)
            {
                var propertyExpr = Expression.Property(param, prop);

                if (string.IsNullOrWhiteSpace(queryValue))
                {
                    var leftExpr = Expression.Equal(propertyExpr, Expression.Constant(null));

                    var asQueryableCallExpr = Expression.Call(
                        typeof(Queryable),
                        "AsQueryable",
                        new[] { relatedType },
                        propertyExpr);
                    var anyCallExpr = Expression.Call(
                        typeof(Queryable),
                        "Any",
                        new[] { relatedType },
                        asQueryableCallExpr);
                    var rightExpr = Expression.Not(anyCallExpr);

                    return(Expression.OrElse(leftExpr, rightExpr));
                }
                else
                {
                    var leftExpr = Expression.NotEqual(propertyExpr, Expression.Constant(null));

                    var idValue  = queryValue.Trim();
                    var idExpr   = Expression.Constant(idValue);
                    var anyParam = Expression.Parameter(relatedType);
                    var relatedIdPropertyExpr         = Expression.Property(anyParam, relatedIdProperty);
                    var relatedIdPropertyEqualsIdExpr = Expression.Equal(relatedIdPropertyExpr, idExpr);
                    var anyPredicateExpr    = Expression.Lambda(relatedIdPropertyEqualsIdExpr, anyParam);
                    var asQueryableCallExpr = Expression.Call(
                        typeof(Queryable),
                        "AsQueryable",
                        new[] { relatedType },
                        propertyExpr);
                    var rightExpr = Expression.Call(
                        typeof(Queryable),
                        "Any",
                        new[] { relatedType },
                        asQueryableCallExpr,
                        anyPredicateExpr);

                    return(Expression.AndAlso(leftExpr, rightExpr));
                }
            }
            else
            {
                var propertyExpr = Expression.Property(param, prop);

                if (string.IsNullOrWhiteSpace(queryValue))
                {
                    return(Expression.Equal(propertyExpr, Expression.Constant(null)));
                }

                var leftExpr = Expression.NotEqual(propertyExpr, Expression.Constant(null));

                var idValue = queryValue.Trim();
                var idExpr  = Expression.Constant(idValue);
                var relatedIdPropertyExpr = Expression.Property(propertyExpr, relatedIdProperty);
                var rightExpr             = Expression.Equal(relatedIdPropertyExpr, idExpr);

                return(Expression.AndAlso(leftExpr, rightExpr));
            }
        }
 /// <summary>
 /// Gets a metadata object to serialize alongside the link URL for related resource links.
 /// </summary>
 /// <returns></returns>
 protected virtual IMetadata GetMetadataForRelatedResourceLink <TResource>(TResource relationshipOwner, ResourceTypeRelationship property)
 {
     return(null);
 }
        public ILink GetRelatedResourceLink <TResource>(TResource relationshipOwner, IResourceTypeRegistry resourceTypeRegistry, ResourceTypeRelationship property, string baseUrl)
        {
            var url      = BuildRelatedResourceUrl(relationshipOwner, resourceTypeRegistry, property, baseUrl);
            var metadata = GetMetadataForRelatedResourceLink(relationshipOwner, property);

            return(new Link(url, metadata));
        }
Esempio n. 10
0
        /// <summary>
        /// Generic method for getting the related resources for a to-many relationship
        /// </summary>
        protected async Task <IResourceCollectionDocument> GetRelatedToMany <TRelated>(string id,
                                                                                       ResourceTypeRelationship relationship, HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var param        = Expression.Parameter(typeof(T));
            var accessorExpr = Expression.Property(param, relationship.Property);
            var lambda       = Expression.Lambda <Func <T, IEnumerable <TRelated> > >(accessorExpr, param);

            var primaryEntityQuery = FilterById <T>(id, _resourceTypeRegistration);

            // We have to see if the resource even exists, so we can throw a 404 if it doesn't
            var relatedResource = await primaryEntityQuery.FirstOrDefaultAsync(cancellationToken);

            if (relatedResource == null)
            {
                throw JsonApiException.CreateForNotFound(string.Format("No resource of type `{0}` exists with id `{1}`.",
                                                                       _resourceTypeRegistration.ResourceTypeName, id));
            }

            var relatedResourceQuery = primaryEntityQuery.SelectMany(lambda);
            var sortExpressions      = _sortExpressionExtractor.ExtractSortExpressions(request);

            return(await _queryableResourceCollectionDocumentBuilder.BuildDocument(relatedResourceQuery, request, sortExpressions, cancellationToken));
        }
        /// <summary>
        /// Sets the value of a to-many relationship
        /// </summary>
        protected void SetToManyRelationshipValue <TRelated>(object material, IEnumerable <object> relatedObjects, ResourceTypeRelationship relationship)
        {
            var currentValue = relationship.Property.GetValue(material);
            var typedArray   = relatedObjects.Select(o => (TRelated)o).ToArray();

            if (relationship.Property.PropertyType.IsAssignableFrom(typeof(List <TRelated>)))
            {
                if (currentValue == null)
                {
                    relationship.Property.SetValue(material, typedArray.ToList());
                }
                else
                {
                    var listCurrentValue = (ICollection <TRelated>)currentValue;
                    var itemsToAdd       = typedArray.Except(listCurrentValue);
                    var itemsToRemove    = listCurrentValue.Except(typedArray).ToList();

                    foreach (var related in itemsToAdd)
                    {
                        listCurrentValue.Add(related);
                    }

                    foreach (var related in itemsToRemove)
                    {
                        listCurrentValue.Remove(related);
                    }
                }
            }
            else
            {
                relationship.Property.SetValue(material, typedArray);
            }
        }