Example #1
0
        private void SetValues(EntityEntry dbEntry, DataModificationItem item, Type resourceType)
        {
            if (item.IsFullReplaceUpdateRequest)
            {
                // The algorithm for a "FullReplaceUpdate" is taken from ObjectContextServiceProvider.ResetResource
                // in WCF DS, and works as follows:
                //  - Create a new, blank instance of the entity.
                //  - Copy over the key values and set any updated values from the client on the new instance.
                //  - Then apply all the properties of the new instance to the instance to be updated.
                //    This will set any unspecified properties to their default value.
                var newInstance = Activator.CreateInstance(resourceType);

                this.SetValues(newInstance, resourceType, item.ResourceKey);
                this.SetValues(newInstance, resourceType, item.LocalValues);

                dbEntry.CurrentValues.SetValues(newInstance);
            }
            else
            {
                foreach (var propertyPair in item.LocalValues)
                {
                    var propertyEntry = dbEntry.Property(propertyPair.Key);
                    var value         = propertyPair.Value;
                    if (value == null)
                    {
                        // If the property value is null, we set null in the item too.
                        propertyEntry.CurrentValue = null;
                        continue;
                    }

                    Type type = null;
                    if (propertyEntry.CurrentValue != null)
                    {
                        type = propertyEntry.CurrentValue.GetType();
                    }
                    else
                    {
                        // If property does not have value now, will get property type from model
                        var propertyInfo = dbEntry.Entity.GetType().GetProperty(propertyPair.Key);
                        type = propertyInfo.PropertyType;
                    }

                    // todo: complex property detection removed. Not sure whether IReadOnlyDictionary is enough.
                    if (value is IReadOnlyDictionary <string, object> dic)
                    {
                        value = propertyEntry.CurrentValue;
                        this.SetValues(value, type, dic);
                    }

                    propertyEntry.CurrentValue = this.ConvertToEfValue(type, value);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Handles a POST request to create an entity.
        /// </summary>
        /// <param name="edmEntityObject">The entity object to create.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The task object that contains the creation result.</returns>
        public async Task <IHttpActionResult> Post(EdmEntityObject edmEntityObject, CancellationToken cancellationToken)
        {
            if (edmEntityObject == null)
            {
                throw new ArgumentNullException(nameof(edmEntityObject));
            }

            CheckModelState();
            var path = GetPath();

            if (!(path.NavigationSource is IEdmEntitySet entitySet))
            {
                throw new NotImplementedException(Resources.InsertOnlySupportedOnEntitySet);
            }

            // In case of type inheritance, the actual type will be different from entity type
            var expectedEntityType = path.EdmType;
            var actualEntityType   = path.EdmType as IEdmStructuredType;

            if (edmEntityObject.ActualEdmType != null)
            {
                expectedEntityType = edmEntityObject.ExpectedEdmType;
                actualEntityType   = edmEntityObject.ActualEdmType;
            }

            var postItem = new DataModificationItem(
                entitySet.Name,
                expectedEntityType.GetClrType(Api.ServiceProvider),
                actualEntityType.GetClrType(Api.ServiceProvider),
                RestierEntitySetOperation.Insert,
                null,
                null,
                edmEntityObject.CreatePropertyDictionary(actualEntityType, api, true));

            var changeSetProperty = Request.GetChangeSet();

            if (changeSetProperty == null)
            {
                var changeSet = new ChangeSet();
                changeSet.Entries.Add(postItem);

                var result = await Api.SubmitAsync(changeSet, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                changeSetProperty.ChangeSet.Entries.Add(postItem);

                await changeSetProperty.OnChangeSetCompleted(Request).ConfigureAwait(false);
            }

            return(CreateCreatedODataResult(postItem.Resource));
        }
Example #3
0
        /// <summary>
        /// Handles a POST request to create an entity.
        /// </summary>
        /// <param name="edmEntityObject">The entity object to create.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The task object that contains the creation result.</returns>
        public async Task <IHttpActionResult> Post(EdmEntityObject edmEntityObject, CancellationToken cancellationToken)
        {
            if (!this.ModelState.IsValid)
            {
                return(BadRequest(this.ModelState));
            }

            ODataPath     path      = this.GetPath();
            IEdmEntitySet entitySet = path.NavigationSource as IEdmEntitySet;

            if (entitySet == null)
            {
                throw new NotImplementedException(Resources.InsertOnlySupportedOnEntitySet);
            }

            // In case of type inheritance, the actual type will be different from entity type
            var expectedEntityType = path.EdmType;
            var actualEntityType   = path.EdmType;

            if (edmEntityObject.ActualEdmType != null)
            {
                expectedEntityType = edmEntityObject.ExpectedEdmType;
                actualEntityType   = edmEntityObject.ActualEdmType;
            }

            DataModificationItem postItem = new DataModificationItem(
                entitySet.Name,
                expectedEntityType.GetClrType(Api),
                actualEntityType.GetClrType(Api),
                DataModificationItemAction.Insert,
                null,
                null,
                edmEntityObject.CreatePropertyDictionary());

            RestierChangeSetProperty changeSetProperty = this.Request.GetChangeSet();

            if (changeSetProperty == null)
            {
                ChangeSet changeSet = new ChangeSet();
                changeSet.Entries.Add(postItem);

                SubmitResult result = await Api.SubmitAsync(changeSet, cancellationToken);
            }
            else
            {
                changeSetProperty.ChangeSet.Entries.Add(postItem);

                await changeSetProperty.OnChangeSetCompleted();
            }

            return(this.CreateCreatedODataResult(postItem.Entity));
        }
        public void CanConstruct()
        {
            var instance = new DataModificationItem(
                resourceSetName,
                expectedResourceType,
                actualResourceType,
                action,
                resourceKey,
                originalValues,
                localValues);

            instance.Should().NotBeNull();
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ConventionBasedChangeSetItemAuthorizerTests"/> class.
 /// </summary>
 public ConventionBasedChangeSetItemAuthorizerTests()
 {
     serviceProvider      = new ServiceProviderMock().ServiceProvider.Object;
     dataModificationItem = new DataModificationItem(
         "Test",
         typeof(object),
         typeof(object),
         RestierEntitySetOperation.Insert,
         new Dictionary <string, object>(),
         new Dictionary <string, object>(),
         new Dictionary <string, object>());
     Trace.Listeners.Add(testTraceListener);
 }
        private static object[] GetParameters(ChangeSetItem item)
        {
            switch (item.Type)
            {
            case ChangeSetItemType.DataModification:
                DataModificationItem dataModification = (DataModificationItem)item;
                return(new object[] { dataModification.Resource });

            default:
                throw new InvalidOperationException(string.Format(
                                                        CultureInfo.InvariantCulture, Resources.InvalidChangeSetEntryType, item.Type));
            }
        }
Example #7
0
        private static object CreateFullUpdateInstance(DataModificationItem entry, Type entityType)
        {
            // The algorithm for a "FullReplaceUpdate" is taken from ObjectContextServiceProvider.ResetResource
            // in WCF DS, and works as follows:
            //  - Create a new, blank instance of the entity.
            //  - Copy over the key values and set any updated values from the client on the new instance.
            //  - Then apply all the properties of the new instance to the instance to be updated.
            //    This will set any unspecified properties to their default value.
            object newInstance = Activator.CreateInstance(entityType);

            ChangeSetInitializer.SetValues(newInstance, entityType, entry.ResourceKey);
            ChangeSetInitializer.SetValues(newInstance, entityType, entry.LocalValues);

            return(newInstance);
        }
        /// <inheritdoc/>
        public Task ValidateChangeSetItemAsync(
            SubmitContext context,
            ChangeSetItem item,
            Collection <ChangeSetItemValidationResult> validationResults,
            CancellationToken cancellationToken)
        {
            Ensure.NotNull(validationResults, "validationResults");
            DataModificationItem dataModificationItem = item as DataModificationItem;

            if (dataModificationItem != null)
            {
                object entity = dataModificationItem.Entity;

                // TODO GitHubIssue#50 : should this PropertyDescriptorCollection be cached?
                PropertyDescriptorCollection properties =
                    new DataAnnotations.AssociatedMetadataTypeTypeDescriptionProvider(entity.GetType())
                    .GetTypeDescriptor(entity).GetProperties();

                DataAnnotations.ValidationContext validationContext = new DataAnnotations.ValidationContext(entity);

                foreach (PropertyDescriptor property in properties)
                {
                    validationContext.MemberName = property.Name;

                    IEnumerable <DataAnnotations.ValidationAttribute> validationAttributes =
                        property.Attributes.OfType <DataAnnotations.ValidationAttribute>();
                    foreach (DataAnnotations.ValidationAttribute validationAttribute in validationAttributes)
                    {
                        object value = property.GetValue(entity);
                        DataAnnotations.ValidationResult validationResult =
                            validationAttribute.GetValidationResult(value, validationContext);
                        if (validationResult != DataAnnotations.ValidationResult.Success)
                        {
                            validationResults.Add(new ChangeSetItemValidationResult()
                            {
                                Id           = validationAttribute.GetType().FullName,
                                Message      = validationResult.ErrorMessage,
                                Severity     = EventLevel.Error,
                                Target       = entity,
                                PropertyName = property.Name
                            });
                        }
                    }
                }
            }

            return(Task.WhenAll());
        }
        public static void CanCallGetEntitySetMethodNameWithItemAndRestierPipelineState(
            RestierPipelineState pipelineState,
            RestierEntitySetOperation entitySetOperation,
            string expected)
        {
            var item = new DataModificationItem(
                "Tests",
                typeof(Test),
                typeof(Test),
                entitySetOperation,
                new Mock <IReadOnlyDictionary <string, object> >().Object,
                new Mock <IReadOnlyDictionary <string, object> >().Object,
                new Mock <IReadOnlyDictionary <string, object> >().Object);
            var result = ConventionBasedMethodNameFactory.GetEntitySetMethodName(item, pipelineState);

            result.Should().Be(expected);
        }
Example #10
0
#pragma warning restore CA1062 // Validate public arguments

        /// <summary>
        /// Handles a DELETE request to delete an entity.
        /// </summary>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The task object that contains the deletion result.</returns>
        public async Task <IActionResult> Delete(CancellationToken cancellationToken)
        {
            EnsureInitialized();
            var path = GetPath();

            if (!(path.NavigationSource is IEdmEntitySet entitySet))
            {
                throw new NotImplementedException(Resources.DeleteOnlySupportedOnEntitySet);
            }

            var propertiesInEtag = GetOriginalValues(entitySet);

            if (propertiesInEtag == null)
            {
                throw new StatusCodeException((HttpStatusCode)428, Resources.PreconditionRequired);
            }

            var model = api.GetModel();

            var deleteItem = new DataModificationItem(
                entitySet.Name,
                path.EdmType.GetClrType(model),
                null,
                RestierEntitySetOperation.Delete,
                RestierQueryBuilder.GetPathKeyValues(path),
                propertiesInEtag,
                null);

            var changeSetProperty = HttpContext.GetChangeSet();

            if (changeSetProperty == null)
            {
                var changeSet = new ChangeSet();
                changeSet.Entries.Add(deleteItem);

                var result = await api.SubmitAsync(changeSet, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                changeSetProperty.ChangeSet.Entries.Add(deleteItem);

                await changeSetProperty.OnChangeSetCompleted().ConfigureAwait(false);
            }

            return(StatusCode((int)HttpStatusCode.NoContent));
        }
Example #11
0
        private static async Task PrepareEntry <TEntity>(
            SubmitContext context,
            DbContext dbContext,
            DataModificationItem entry,
            DbSet <TEntity> set,
            CancellationToken cancellationToken) where TEntity : class
        {
            Type    entityType = typeof(TEntity);
            TEntity entity;

            if (entry.DataModificationItemAction == DataModificationItemAction.Insert)
            {
                // TODO: See if Create method is in DbSet<> in future EF7 releases, as the one EF6 has.
                entity = (TEntity)Activator.CreateInstance(typeof(TEntity));

                ChangeSetInitializer.SetValues(entity, entityType, entry.LocalValues);
                set.Add(entity);
            }
            else if (entry.DataModificationItemAction == DataModificationItemAction.Remove)
            {
                entity = (TEntity)await ChangeSetInitializer.FindEntity(context, entry, cancellationToken);

                set.Remove(entity);
            }
            else if (entry.DataModificationItemAction == DataModificationItemAction.Update)
            {
                if (entry.IsFullReplaceUpdateRequest)
                {
                    entity = (TEntity)ChangeSetInitializer.CreateFullUpdateInstance(entry, entityType);
                    dbContext.Update(entity);
                }
                else
                {
                    entity = (TEntity)await ChangeSetInitializer.FindEntity(context, entry, cancellationToken);

                    var dbEntry = dbContext.Attach(entity);
                    ChangeSetInitializer.SetValues(dbEntry, entry);
                }
            }
            else
            {
                throw new NotSupportedException(Resources.DataModificationMustBeCUD);
            }

            entry.Resource = entity;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DataModificationItemTests"/> class.
 /// </summary>
 public DataModificationItemTests()
 {
     resourceSetName      = "Tests";
     expectedResourceType = typeof(Test);
     actualResourceType   = typeof(Test);
     action         = RestierEntitySetOperation.Update;
     resourceKey    = new Dictionary <string, object>();
     originalValues = new Dictionary <string, object>();
     localValues    = new Dictionary <string, object>();
     testClass      = new DataModificationItem(
         resourceSetName,
         expectedResourceType,
         actualResourceType,
         action,
         resourceKey,
         originalValues,
         localValues);
 }
Example #13
0
        /// <summary>
        /// Handles a DELETE request to delete an entity.
        /// </summary>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The task object that contains the deletion result.</returns>
        public async Task <IHttpActionResult> Delete(CancellationToken cancellationToken)
        {
            ODataPath     path      = this.GetPath();
            IEdmEntitySet entitySet = path.NavigationSource as IEdmEntitySet;

            if (entitySet == null)
            {
                throw new NotImplementedException(Resources.DeleteOnlySupportedOnEntitySet);
            }

            var propertiesInEtag = await this.GetOriginalValues(entitySet);

            if (propertiesInEtag == null)
            {
                throw new PreconditionRequiredException(Resources.PreconditionRequired);
            }

            DataModificationItem deleteItem = new DataModificationItem(
                entitySet.Name,
                path.EdmType.GetClrType(Api.ServiceProvider),
                null,
                DataModificationItemAction.Remove,
                RestierQueryBuilder.GetPathKeyValues(path),
                propertiesInEtag,
                null);

            RestierChangeSetProperty changeSetProperty = this.Request.GetChangeSet();

            if (changeSetProperty == null)
            {
                ChangeSet changeSet = new ChangeSet();
                changeSet.Entries.Add(deleteItem);

                SubmitResult result = await Api.SubmitAsync(changeSet, cancellationToken);
            }
            else
            {
                changeSetProperty.ChangeSet.Entries.Add(deleteItem);

                await changeSetProperty.OnChangeSetCompleted(this.Request);
            }

            return(this.StatusCode(HttpStatusCode.NoContent));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ConventionBasedChangeSetItemValidatorTests"/> class.
 /// </summary>
 public ConventionBasedChangeSetItemValidatorTests()
 {
     serviceProvider      = new ServiceProviderMock().ServiceProvider.Object;
     dataModificationItem = new DataModificationItem(
         "Test",
         typeof(object),
         typeof(object),
         RestierEntitySetOperation.Insert,
         new Dictionary <string, object>(),
         new Dictionary <string, object>(),
         new Dictionary <string, object>())
     {
         Resource = new ValidatableEntity()
         {
             Property = "This is a test",
             Number   = 1,
         },
     };
     Trace.Listeners.Add(testTraceListener);
 }
Example #15
0
        /// <summary>
        /// Generates the complete MethodName for a given <see cref="IEdmOperationImport"/>, <see cref="RestierPipelineState"/>, and <see cref="RestierEntitySetOperation"/>.
        /// </summary>
        /// <param name="item">The <see cref="DataModificationItem"/> that contains the details for the EntitySet and the Entities it holds.</param>
        /// <param name="restierPipelineState">The part of the Restier pipeline currently executing.</param>
        /// <returns>A string representing the fully-realized MethodName.</returns>
        /// <returns></returns>
        public static string GetEntitySetMethodName(DataModificationItem item, RestierPipelineState restierPipelineState)
        {
            if ((item.EntitySetOperation == RestierEntitySetOperation.Filter && ExcludedFilterStates.Contains(restierPipelineState)) ||
                restierPipelineState == RestierPipelineState.Submit && ExcludedEntitySetSubmitOperations.Contains(item.EntitySetOperation))
            {
                return(string.Empty);
            }

            var prefix = GetPipelinePrefixInternal(restierPipelineState);

            //RWM: If, for some reason, we don't have a prefix, then we don't have a method for this operation. So don't do anything.
            if (string.IsNullOrWhiteSpace(prefix))
            {
                return(string.Empty);
            }

            var operationName       = GetRestierOperationNameInternal(item.EntitySetOperation, restierPipelineState);
            var suffix              = item.EntitySetOperation != RestierEntitySetOperation.Filter ? GetPipelineSuffixInternal(restierPipelineState) : string.Empty;
            var entityReferenceName = GetEntityReferenceNameInternal(item.EntitySetOperation, item.ResourceSetName, item.ExpectedResourceType.Name);

            return($"{prefix}{operationName}{suffix}{entityReferenceName}");
        }
Example #16
0
        private static async Task <object> FindEntity(
            SubmitContext context,
            DataModificationItem item,
            CancellationToken cancellationToken)
        {
            IQueryable query = context.ApiContext.GetQueryableSource(item.EntitySetName);

            query = item.ApplyTo(query);

            QueryResult result = await context.ApiContext.QueryAsync(new QueryRequest(query), cancellationToken);

            object entity = result.Results.SingleOrDefault();

            if (entity == null)
            {
                throw new ResourceNotFoundException(Resources.ResourceNotFound);
            }

            // This means no If-Match or If-None-Match header
            if (item.OriginalValues == null || item.OriginalValues.Count == 0)
            {
                return(entity);
            }

            var etagEntity = item.ApplyEtag(result.Results.AsQueryable()).SingleOrDefault();

            if (etagEntity == null)
            {
                // If ETAG does not match, should return 412 Precondition Failed
                var message = string.Format(
                    CultureInfo.InvariantCulture,
                    Resources.PreconditionCheckFailed,
                    new object[] { item.DataModificationItemAction, entity });
                throw new PreconditionFailedException(message);
            }

            return(etagEntity);
        }
Example #17
0
        private static object FindResource(
            object instance,
            SubmitContext context,
            DataModificationItem item,
            CancellationToken cancellationToken)
        {
            var    entitySetPropertyInfo = GetEntitySetPropertyInfoFromDataModificationItem(instance, item);
            var    originSet             = entitySetPropertyInfo.GetValue(instance);
            object resource      = null;
            Type   resourceType  = null;
            var    enumerableSet = originSet as IEnumerable <object>;

            if (enumerableSet != null)
            {
                resourceType = originSet.GetType().GetGenericArguments()[0];
                foreach (var o in enumerableSet)
                {
                    var foundFlag = true;
                    foreach (var keyVal in item.ResourceKey)
                    {
                        var entityProp = o.GetType().GetProperty(keyVal.Key);
                        if (entityProp != null)
                        {
                            foundFlag &= entityProp.GetValue(o).Equals(keyVal.Value);
                        }
                        else
                        {
                            foundFlag = false;
                        }

                        if (!foundFlag)
                        {
                            break;
                        }
                    }

                    if (foundFlag)
                    {
                        resource = Convert.ChangeType(o, resourceType);
                        break;
                    }
                }
            }

            if (resource == null)
            {
                throw new ResourceNotFoundException("Resource Not Found");
            }

            // This means no If-Match or If-None-Match header
            if (item.OriginalValues == null || item.OriginalValues.Count == 0)
            {
                return(resource);
            }

            // Make a list of resource as IQueryable to valid etag
            var listOfItemType = typeof(List <>).MakeGenericType(resourceType);
            var list           = Activator.CreateInstance(listOfItemType);

            listOfItemType.GetMethod("Add").Invoke(list, new[] { resource });
            var method = typeof(Queryable).GetMethod(
                "AsQueryable",
                BindingFlags.Static | BindingFlags.Public,
                null,
                new[] { listOfItemType },
                null);

            resource = item.ValidateEtag(method.Invoke(list, new[] { list }) as IQueryable);
            return(resource);
        }
Example #18
0
        private async Task <IHttpActionResult> Update(
            EdmEntityObject edmEntityObject,
            bool isFullReplaceUpdate,
            CancellationToken cancellationToken)
        {
            CheckModelState();
            var path      = GetPath();
            var entitySet = path.NavigationSource as IEdmEntitySet;

            if (entitySet == null)
            {
                throw new NotImplementedException(Resources.UpdateOnlySupportedOnEntitySet);
            }

            var propertiesInEtag = await GetOriginalValues(entitySet).ConfigureAwait(false);

            if (propertiesInEtag == null)
            {
                throw new PreconditionRequiredException(Resources.PreconditionRequired);
            }

            // In case of type inheritance, the actual type will be different from entity type
            // This is only needed for put case, and does not need for patch case
            // For put request, it will create a new, blank instance of the entity.
            // copy over the key values and set any updated values from the client on the new instance.
            // Then apply all the properties of the new instance to the instance to be updated.
            // This will set any unspecified properties to their default value.
            var expectedEntityType = path.EdmType;
            var actualEntityType   = path.EdmType as IEdmStructuredType;

            if (edmEntityObject.ActualEdmType != null)
            {
                expectedEntityType = edmEntityObject.ExpectedEdmType;
                actualEntityType   = edmEntityObject.ActualEdmType;
            }

            var updateItem = new DataModificationItem(
                entitySet.Name,
                expectedEntityType.GetClrType(Api.ServiceProvider),
                actualEntityType.GetClrType(Api.ServiceProvider),
                RestierEntitySetOperation.Update,
                RestierQueryBuilder.GetPathKeyValues(path),
                propertiesInEtag,
                edmEntityObject.CreatePropertyDictionary(actualEntityType, api, false))
            {
                IsFullReplaceUpdateRequest = isFullReplaceUpdate
            };

            var changeSetProperty = Request.GetChangeSet();

            if (changeSetProperty == null)
            {
                var changeSet = new ChangeSet();
                changeSet.Entries.Add(updateItem);

                var result = await Api.SubmitAsync(changeSet, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                changeSetProperty.ChangeSet.Entries.Add(updateItem);

                await changeSetProperty.OnChangeSetCompleted(Request).ConfigureAwait(false);
            }

            return(CreateUpdatedODataResult(updateItem.Resource));
        }
        private void SetValues(DbEntityEntry dbEntry, DataModificationItem item, Type resourceType)
        {
            if (item.IsFullReplaceUpdateRequest)
            {
                // The algorithm for a "FullReplaceUpdate" is taken from ObjectContextServiceProvider.ResetResource
                // in WCF DS, and works as follows:
                //  - Create a new, blank instance of the entity.
                //  - Copy over the key values and set any updated values from the client on the new instance.
                //  - Then apply all the properties of the new instance to the instance to be updated.
                //    This will set any unspecified properties to their default value.
                object newInstance = Activator.CreateInstance(resourceType);

                SetValues(newInstance, resourceType, item.ResourceKey);
                SetValues(newInstance, resourceType, item.LocalValues);

                dbEntry.CurrentValues.SetValues(newInstance);
            }
            else
            {
                foreach (KeyValuePair <string, object> propertyPair in item.LocalValues)
                {
                    DbPropertyEntry propertyEntry = dbEntry.Property(propertyPair.Key);
                    object          value         = propertyPair.Value;
                    if (value == null)
                    {
                        // If the property value is null, we set null in the item too.
                        propertyEntry.CurrentValue = null;
                        continue;
                    }

                    Type type = null;
                    if (propertyEntry.CurrentValue != null)
                    {
                        type = propertyEntry.CurrentValue.GetType();
                    }
                    else
                    {
                        // If property does not have value now, will get property type from model
                        var propertyInfo = dbEntry.Entity.GetType().GetProperty(propertyPair.Key);
                        type = propertyInfo.PropertyType;
                    }

                    if (propertyEntry is DbComplexPropertyEntry)
                    {
                        var dic = value as IReadOnlyDictionary <string, object>;
                        if (dic == null)
                        {
                            throw new NotSupportedException(string.Format(
                                                                CultureInfo.InvariantCulture,
                                                                Resources.UnsupportedPropertyType,
                                                                propertyPair.Key));
                        }

                        value = propertyEntry.CurrentValue;
                        SetValues(value, type, dic);
                    }

                    propertyEntry.CurrentValue = ConvertToEfValue(type, value);
                }
            }
        }
Example #20
0
        private async Task HandleEntitySet <TEntity>(SubmitContext context, DbContext dbContext, DataModificationItem entry, Type resourceType, CancellationToken cancellationToken)
            where TEntity : class, new()
        {
            var set = dbContext.Set <TEntity>();

            TEntity resource;

            if (entry.EntitySetOperation == RestierEntitySetOperation.Insert)
            {
                resource = new TEntity();

                this.SetValues(resource, resourceType, entry.LocalValues);
                set.Add(resource);
            }
            else if (entry.EntitySetOperation == RestierEntitySetOperation.Delete)
            {
                resource = (await FindResource(context, entry, cancellationToken).ConfigureAwait(false)) as TEntity;
                set.Remove(resource);
            }
            else if (entry.EntitySetOperation == RestierEntitySetOperation.Update)
            {
                resource = (await FindResource(context, entry, cancellationToken).ConfigureAwait(false)) as TEntity;

                var dbEntry = dbContext.Entry(resource);
                this.SetValues(dbEntry, entry, resourceType);
            }
            else
            {
                throw new NotSupportedException(Resources.DataModificationMustBeCUD);
            }

            entry.Resource = resource;
        }