示例#1
0
        private void CheckEntityLock(DbContext writableContext, IList <Guid> lockedIds)
        {
            foreach (
                var updatedEntityEntry in
                writableContext.ChangeTracker.Entries <EntityIdentifierBase>().Where(x => x.State == EntityState.Modified))
            {
                EntityLockResult lockResult = null;
                if (updatedEntityEntry.Entity is ILockable)
                {
                    lockResult = lockingManager.IsLockedBy(updatedEntityEntry.Entity);
                }
                var versionedEntity = updatedEntityEntry.Entity as IVersionedVolume;
                if (versionedEntity != null)
                {
                    lockResult = lockingManager.IsLockedBy(versionedEntity.UnificRootId);
                }
                if (lockResult != null)
                {
                    switch (lockResult.LockStatus)
                    {
                    case EntityLockEnum.Unlocked:
                        continue;

                    case EntityLockEnum.LockedForCurrent:
                        lockedIds.Add(versionedEntity.UnificRootId);
                        break;

                    default:
                        throw new LockException("", new List <string> {
                            lockResult.LockedBy
                        });
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Push changes done in context into database
        /// </summary>
        /// <param name="saveMode"></param>
        /// <param name="parentEntity">Logical parent entity to mark as updated when committing changes to database</param>
        /// <param name="userName">The user name for user. Used in console application (PTV.DataMapper.ConsoleApp) where there is no Httpcontext</param>
        public void Save(SaveMode saveMode = SaveMode.Normal, object parentEntity = null, string userName = null)
        {
            IList <VmLogEntry> logEntries = new List <VmLogEntry>();
            IList <Guid>       lockedIds  = new List <Guid>();

            var writableContext = this.DbContext as DbContext;

            logger.LogDebug("*** Before detect changes of entities ***");
            CreateLogs(writableContext);

//            writableContext.ChangeTracker.Entries().ToList().Where(i => i.Properties.Any(m => m.IsModified)).SelectMany(e => e.Properties.Where(m => m.IsModified && (m.OriginalValue?.ToString() == m.CurrentValue?.ToString()))).ForEach(e => e.IsModified = false);
//
//
//            var allEntries = writableContext.ChangeTracker.Entries().ToList().Where(i => i.State == EntityState.Modified || i.Properties.Any(m => m.IsModified || (m.OriginalValue?.ToString() != m.CurrentValue?.ToString())));
//            allEntries.ForEach(e =>
//            {
//                var propertiesStatuses = e.Properties.Select(p => $"{p.Metadata.Name} is modified: {p.IsModified}, original: {p.OriginalValue}, new value: {p.CurrentValue}").ToList();
//                Console.WriteLine($"{e.Metadata.Name} is {e.State}");
//                propertiesStatuses.ForEach(p =>
//                {
//                    Console.WriteLine($" - {p}");
//                });
//            });


            writableContext.ChangeTracker.DetectChanges();
            logger.LogDebug("*** After detect changes of entities ***");
            CreateLogs(writableContext);
            userName = GetUserNameForAuditing(saveMode, userName);
            if (!string.IsNullOrEmpty(userName) || saveMode == SaveMode.NonTrackedDataMigration)
            {
                if (saveMode != SaveMode.NonTrackedDataMigration)
                {
                    if (parentEntity != null && writableContext.ChangeTracker.Entries <IAuditing>().Any(x => x.State == EntityState.Added || x.State == EntityState.Modified))
                    {
                        writableContext.Entry(parentEntity).Property("Modified").IsModified   = true;
                        writableContext.Entry(parentEntity).Property("ModifiedBy").IsModified = true;
                    }
                    if (saveMode != SaveMode.AllowAnonymous)
                    {
                        CheckRoles(saveMode, writableContext);
                        CheckEntityLock(writableContext, lockedIds);
                    }
                }

                var dateToSave  = DateTime.UtcNow;
                var operationId = dateToSave.ToString("O") + "-" + Guid.NewGuid();
                foreach (var updatedEntityEntry in writableContext.ChangeTracker.Entries <IAuditing>().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified))
                {
                    ApplyFormattingToPropertiess(updatedEntityEntry);
                    SetAuditingFields(updatedEntityEntry, userName, dateToSave, saveMode);
                    SetOperationInfoFields(updatedEntityEntry, operationId, dateToSave);
                    logEntries.Add(GetLogEntry(updatedEntityEntry.Entity));
                }
            }
            else
            {
                throw new Exception(CoreMessages.AnonymousSaveNotAllowed);
            }

            // unlock all entries

            var lockResults = lockingManager.UnLockEntities(this, lockedIds);
            EntityLockResult lockedEntity = lockResults.Values.FirstOrDefault(i => i.LockStatus != EntityLockEnum.Unlocked);

            if (lockedEntity != null)
            {
                throw new LockException("", new List <string>()
                {
                    lockedEntity.LockedBy
                });
            }

            // save changes
            writableContext.SaveChanges();
            // Let's add the log entries only when we are sure database changes have been successfully saved into database.
            logger.LogDBEntries(logEntries);
        }