public async Task Invoke(CRUDContext <TService> ctx)
        {
            IServiceOperationsHelper <TService> serviceHelper = ctx.ServiceContainer.GetServiceHelper();
            IDataHelper <TService> dataHelper = ctx.ServiceContainer.GetDataHelper();

            Metadata.RunTimeMetadata metadata       = ctx.Service.GetMetadata();
            ChangeSetRequest         changeSet      = ctx.Request;
            IChangeSetGraph          graph          = ctx.Properties.Get <IChangeSetGraph>(CRUDContext <TService> .CHANGE_GRAPH_KEY) ?? throw new InvalidOperationException("Could not get Graph changes from properties");
            CRUDServiceMethods       serviceMethods = ctx.Properties.Get <CRUDServiceMethods>(CRUDContext <TService> .CHANGE_METHODS_KEY) ?? throw new InvalidOperationException("Could not get CRUD Service methods from properties");

            RequestContext req = CRUDContext <TService> .CreateRequestContext(ctx.Service, changeSet);

            using (RequestCallContext callContext = new RequestCallContext(req))
            {
                await serviceMethods.ExecuteChangeSet();

                await serviceHelper.AfterExecuteChangeSet(changeSet);

                await serviceMethods.AfterChangeSetExecuted();

                foreach (RowInfo rowInfo in graph.AllList)
                {
                    if (rowInfo.changeType != ChangeType.Deleted)
                    {
                        serviceHelper.UpdateRowInfoAfterUpdates(rowInfo);
                    }
                }

                SubResultList subResults = new SubResultList();
                await serviceHelper.AfterChangeSetCommited(changeSet, subResults);

                await serviceMethods.AfterChangeSetCommited(subResults);

                SubsetsGenerator subsetsGenerator = new SubsetsGenerator(metadata, dataHelper);
                ctx.Response.subsets = subsetsGenerator.CreateSubsets(subResults);
            }


            await _next(ctx);
        }
Exemple #2
0
        protected async Task <bool> ApplyChangeSet(ChangeSet changeSet)
        {
            AuthorizeChangeSet(changeSet);
            var metadata = MetadataHelper.GetInitializedMetadata(this);
            var graph    = new ChangeSetGraph(changeSet, metadata);

            graph.Prepare();

            foreach (var rowInfo in graph.insertList)
            {
                var dbSet = changeSet.dbSets.Where(d => d.dbSetName == rowInfo.dbSetInfo.dbSetName).Single();
                var req   = new RequestContext(this, changeSet: changeSet, dbSet: dbSet, rowInfo: rowInfo,
                                               operation: ServiceOperationType.SaveChanges);
                using (var callContext = new RequestCallContext(req))
                {
                    rowInfo.changeState = new EntityChangeState {
                        ParentRows = graph.GetParents(rowInfo)
                    };
                    ApplyChangesToEntity(rowInfo);
                }
            }

            foreach (var rowInfo in graph.updateList)
            {
                var dbSet = changeSet.dbSets.Where(d => d.dbSetName == rowInfo.dbSetInfo.dbSetName).Single();
                var req   = new RequestContext(this, changeSet: changeSet, dbSet: dbSet, rowInfo: rowInfo,
                                               operation: ServiceOperationType.SaveChanges);
                using (var callContext = new RequestCallContext(req))
                {
                    rowInfo.changeState = new EntityChangeState();
                    ApplyChangesToEntity(rowInfo);
                }
            }

            foreach (var rowInfo in graph.deleteList)
            {
                var dbSet = changeSet.dbSets.Where(d => d.dbSetName == rowInfo.dbSetInfo.dbSetName).Single();
                var req   = new RequestContext(this, changeSet: changeSet, dbSet: dbSet, rowInfo: rowInfo,
                                               operation: ServiceOperationType.SaveChanges);
                using (var callContext = new RequestCallContext(req))
                {
                    rowInfo.changeState = new EntityChangeState();
                    ApplyChangesToEntity(rowInfo);
                }
            }

            var hasErrors = false;

            //Validation step
            foreach (var rowInfo in graph.insertList)
            {
                var dbSet = changeSet.dbSets.Where(d => d.dbSetName == rowInfo.dbSetInfo.dbSetName).Single();
                var req   = new RequestContext(this, changeSet: changeSet, dbSet: dbSet, rowInfo: rowInfo,
                                               operation: ServiceOperationType.SaveChanges);
                using (var callContext = new RequestCallContext(req))
                {
                    if (!await _serviceHelper.ValidateEntity(metadata, req).ConfigureAwait(false))
                    {
                        rowInfo.invalid = rowInfo.changeState.ValidationErrors;
                        hasErrors       = true;
                    }
                }
            }

            //Validation step
            foreach (var rowInfo in graph.updateList)
            {
                var dbSet = changeSet.dbSets.Where(d => d.dbSetName == rowInfo.dbSetInfo.dbSetName).Single();
                var req   = new RequestContext(this, changeSet: changeSet, dbSet: dbSet, rowInfo: rowInfo,
                                               operation: ServiceOperationType.SaveChanges);
                using (var callContext = new RequestCallContext(req))
                {
                    if (!await _serviceHelper.ValidateEntity(metadata, req).ConfigureAwait(false))
                    {
                        rowInfo.invalid = rowInfo.changeState.ValidationErrors;
                        hasErrors       = true;
                    }
                }
            }

            if (hasErrors)
            {
                return(false);
            }

            var reqCntxt = new RequestContext(this, changeSet: changeSet, operation: ServiceOperationType.SaveChanges);

            using (var callContext = new RequestCallContext(reqCntxt))
            {
                await ExecuteChangeSet().ConfigureAwait(false);


                foreach (var rowInfo in graph.allList)
                {
                    if (rowInfo.changeType != ChangeType.Deleted)
                    {
                        _serviceHelper.UpdateRowInfoAfterUpdates(rowInfo);
                    }
                    else
                    {
                        rowInfo.values = null;
                    }
                }


                //Track changes step
                foreach (var rowInfo in graph.allList)
                {
                    TrackChangesToEntity(rowInfo);
                }
            }
            //OK, All updates are commited
            return(true);
        }