예제 #1
0
        /// <summary>
        /// Update the given existing entity with the new entity, preserving the history for the original.
        /// </summary>
        /// <param name="updateData"></param>
        /// <param name="originalData"></param>
        /// <returns></returns>
        public async Task UpdateWithHistoryAsync(EntityPackage updateData, long user, EntityPackage originalData = null)
        {
            logger.LogTrace($"WriteHistoric called for entity {updateData.Entity.id}");

            //The original isn't necessary; we can find it using the id from our apparently updated data
            if (originalData == null)
            {
                originalData = await provider.FindByIdAsync(updateData.Entity.id);
            }

            var history = await CreateHistoricCopyAsync(originalData.Entity);

            try
            {
                //Bring all the existing over to this historic entity
                history.Relink(originalData.Values, originalData.Relations);

                //WE have to link the new stuff to US because we want to write everything all at once
                originalData.Entity.Relink(updateData.Values, updateData.Relations);

                //Add the historic link back to the history copy from the
                originalData.Relations.Add(NewHistoryLink(updateData.Entity, history));

                //A special thing: the values and relations need to be NEW for the update data
                updateData.Relations.ForEach(x => x.id = 0);
                updateData.Values.ForEach(x => x.id    = 0);

                //We're writing the entirety of the "update" data.
                var writes = updateData.FlattenPackage();

                //Also writing the relinked original stuff.
                writes.AddRange(originalData.Values);
                writes.AddRange(originalData.Relations);

                writes.Add(activityService.MakeActivity(updateData.Entity, user, Keys.UpdateAction, history.id.ToString()));

                await provider.WriteAsync(writes.ToArray());
            }
            catch
            {
                logger.LogError("Failure during historic update, trying to undo... Exception bubbling...");
                await provider.DeleteAsync(history);

                throw;
            }
        }