Ejemplo n.º 1
0
 public void SetRelationships(object parent, RelationshipAttribute relationship, IEnumerable <string> relationshipIds)
 {
     if (relationship.IsHasMany)
     {
         var entities = _context.Set <T>().Where(x => relationshipIds.Contains(x.StringId)).ToList();
         relationship.SetValue(parent, entities);
     }
     else
     {
         var entity = _context.Set <T>().SingleOrDefault(x => relationshipIds.First() == x.StringId);
         relationship.SetValue(parent, entity);
     }
 }
        private object SetHasManyRelationship(object entity,
                                              PropertyInfo[] entityProperties,
                                              RelationshipAttribute attr,
                                              ContextEntity contextEntity,
                                              Dictionary <string, RelationshipData> relationships,
                                              List <DocumentData> included = null)
        {
            var relationshipName = attr.PublicRelationshipName;

            if (relationships.TryGetValue(relationshipName, out RelationshipData relationshipData))
            {
                var data = (List <ResourceIdentifierObject>)relationshipData.ExposedData;

                if (data == null)
                {
                    return(entity);
                }

                var relatedResources = relationshipData.ManyData.Select(r =>
                {
                    var instance = GetIncludedRelationship(r, included, attr);
                    return(instance);
                });

                var convertedCollection = TypeHelper.ConvertCollection(relatedResources, attr.Type);

                attr.SetValue(entity, convertedCollection);

                _jsonApiContext.HasManyRelationshipPointers.Add(attr, convertedCollection);
            }

            return(entity);
        }
        private async Task UpdateOneToManyAsync(IIdentifiable parent, RelationshipAttribute relationship, IEnumerable <string> relationshipIds)
        {
            IEnumerable value;

            if (!relationshipIds.Any())
            {
                var collectionType = relationship.Property.PropertyType.ToConcreteCollectionType();
                value = (IEnumerable)TypeHelper.CreateInstance(collectionType);
            }
            else
            {
                var idType   = TypeHelper.GetIdType(relationship.RightType);
                var typedIds = relationshipIds.CopyToList(idType, stringId => TypeHelper.ConvertType(stringId, idType));

                // [1, 2, 3]
                var target = Expression.Constant(typedIds);
                // (Person p) => ...
                ParameterExpression parameter = Expression.Parameter(typeof(TRelatedResource));
                // (Person p) => p.Id
                Expression idMember = Expression.Property(parameter, nameof(Identifiable.Id));
                // [1,2,3].Contains(p.Id)
                var callContains   = Expression.Call(typeof(Enumerable), nameof(Enumerable.Contains), new[] { idMember.Type }, target, idMember);
                var containsLambda = Expression.Lambda <Func <TRelatedResource, bool> >(callContains, parameter);

                var resultSet = await _context.Set <TRelatedResource>().Where(containsLambda).ToListAsync();

                value = resultSet.CopyToTypedCollection(relationship.Property.PropertyType);
            }

            relationship.SetValue(parent, value, _resourceFactory);
        }
Ejemplo n.º 4
0
        private void ParseDataForRelationship(RelationshipAttribute relationship,
                                              ResourceContext secondaryResourceContext,
                                              AtomicOperationObject operation, IIdentifiable primaryResource)
        {
            if (relationship is HasOneAttribute)
            {
                if (operation.ManyData != null)
                {
                    throw new JsonApiSerializationException(
                              "Expected single data element for to-one relationship.",
                              $"Expected single data element for '{relationship.PublicName}' relationship.",
                              atomicOperationIndex: AtomicOperationIndex);
                }

                if (operation.SingleData != null)
                {
                    ValidateSingleDataForRelationship(operation.SingleData, secondaryResourceContext, "data");

                    var secondaryResource = ParseResourceObject(operation.SingleData);
                    relationship.SetValue(primaryResource, secondaryResource);
                }
            }
            else if (relationship is HasManyAttribute)
            {
                if (operation.ManyData == null)
                {
                    throw new JsonApiSerializationException(
                              "Expected data[] element for to-many relationship.",
                              $"Expected data[] element for '{relationship.PublicName}' relationship.",
                              atomicOperationIndex: AtomicOperationIndex);
                }

                var secondaryResources = new List <IIdentifiable>();

                foreach (var resourceObject in operation.ManyData)
                {
                    ValidateSingleDataForRelationship(resourceObject, secondaryResourceContext, "data[]");

                    var secondaryResource = ParseResourceObject(resourceObject);
                    secondaryResources.Add(secondaryResource);
                }

                var rightResources =
                    TypeHelper.CopyToTypedCollection(secondaryResources, relationship.Property.PropertyType);
                relationship.SetValue(primaryResource, rightResources);
            }
        }
Ejemplo n.º 5
0
        public async Task UpdateRelationshipsAsync(object parent, RelationshipAttribute relationship, IEnumerable <string> relationshipIds)
        {
            var relationshipType = relationship.Type;

            if (relationship.IsHasMany)
            {
                var entities = _context.GetDbSet <T>().Where(x => relationshipIds.Contains(x.Id.ToString())).ToList();
                relationship.SetValue(parent, entities);
            }
            else
            {
                var entity = _context.GetDbSet <T>().SingleOrDefault(x => relationshipIds.First() == x.Id.ToString());
                relationship.SetValue(parent, entity);
            }

            await _context.SaveChangesAsync();
        }
        protected async Task UpdateRelationshipAsync(RelationshipAttribute relationship, TResource leftResource, object valueToAssign,
                                                     PlaceholderResourceCollector collector, CancellationToken cancellationToken)
        {
            object trackedValueToAssign = EnsureRelationshipValueToAssignIsTracked(valueToAssign, relationship.Property.PropertyType, collector);

            if (RequireLoadOfInverseRelationship(relationship, trackedValueToAssign))
            {
                EntityEntry entityEntry         = _dbContext.Entry(trackedValueToAssign);
                string      inversePropertyName = relationship.InverseNavigationProperty.Name;

                await entityEntry.Reference(inversePropertyName).LoadAsync(cancellationToken);
            }

            relationship.SetValue(leftResource, trackedValueToAssign);
        }
Ejemplo n.º 7
0
        private async Task UpdateOneToManyAsync(IIdentifiable parent, RelationshipAttribute relationship, IEnumerable <string> relationshipIds)
        {
            var value = new List <TRelatedResource>();

            if (relationshipIds.Any())
            {   // [1, 2, 3]
                var target = Expression.Constant(TypeHelper.ConvertListType(relationshipIds, TypeHelper.GetIdentifierType(relationship.RightType)));
                // (Person p) => ...
                ParameterExpression parameter = Expression.Parameter(typeof(TRelatedResource));
                // (Person p) => p.Id
                Expression idMember = Expression.Property(parameter, nameof(Identifiable.Id));
                // [1,2,3].Contains(p.Id)
                var callContains   = Expression.Call(typeof(Enumerable), nameof(Enumerable.Contains), new[] { idMember.Type }, target, idMember);
                var containsLamdda = Expression.Lambda <Func <TRelatedResource, bool> >(callContains, parameter);
                value = await _context.Set <TRelatedResource>().Where(containsLamdda).ToListAsync();
            }
            relationship.SetValue(parent, value);
        }
Ejemplo n.º 8
0
        private async Task UpdateOneToOneAsync(IIdentifiable parent, RelationshipAttribute relationship, IEnumerable <string> relationshipIds)
        {
            TRelatedResource value = null;

            if (relationshipIds.Any())
            {   // newOwner.id
                var target = Expression.Constant(TypeHelper.ConvertType(relationshipIds.First(), TypeHelper.GetIdentifierType(relationship.RightType)));
                // (Person p) => ...
                ParameterExpression parameter = Expression.Parameter(typeof(TRelatedResource));
                // (Person p) => p.Id
                Expression idMember = Expression.Property(parameter, nameof(Identifiable.Id));
                // newOwner.Id.Equals(p.Id)
                Expression callEquals   = Expression.Call(idMember, nameof(object.Equals), null, target);
                var        equalsLambda = Expression.Lambda <Func <TRelatedResource, bool> >(callEquals, parameter);
                value = await _context.Set <TRelatedResource>().FirstOrDefaultAsync(equalsLambda);
            }
            relationship.SetValue(parent, value);
        }