示例#1
0
        public static DbEntityEntry Refresh(this DbEntityEntry tracking, RefreshConflict refreshMode)
        {
            tracking.NotNull(nameof(tracking));

            switch (refreshMode)
            {
            case RefreshConflict.StoreWins:
            {
                // When entity is already deleted in database, Reload sets tracking state to Detached.
                // When entity is already updated in database, Reload sets tracking state to Unchanged.
                tracking.Reload();         // Execute SELECT.
                // Hereafter, SaveChanges ignores this entity.
                break;
            }

            case RefreshConflict.ClientWins:
            {
                DbPropertyValues databaseValues = tracking.GetDatabaseValues();         // Execute SELECT.
                if (databaseValues == null)
                {
                    // When entity is already deleted in database, there is nothing for client to win against.
                    // Manually set tracking state to Detached.
                    tracking.State = EntityState.Detached;
                    // Hereafter, SaveChanges ignores this entity.
                }
                else
                {
                    // When entity is already updated in database, refresh original values, which go to in WHERE clause.
                    tracking.OriginalValues.SetValues(databaseValues);
                    // Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
                }
                break;
            }

            case RefreshConflict.MergeClinetAndStore:
            {
                DbPropertyValues databaseValues = tracking.GetDatabaseValues();         // Execute SELECT.
                if (databaseValues == null)
                {
                    // When entity is already deleted in database, there is nothing for client to merge with.
                    // Manually set tracking state to Detached.
                    tracking.State = EntityState.Detached;
                    // Hereafter, SaveChanges ignores this entity.
                }
                else
                {
                    // When entity is already updated, refresh original values, which go to WHERE clause.
                    DbPropertyValues originalValues = tracking.OriginalValues.Clone();
                    tracking.OriginalValues.SetValues(databaseValues);
                    // If database has an different value for a property, then retain the database value.
                    databaseValues.PropertyNames         // Navigation properties are not included.
                    .Where(property => !object.Equals(originalValues[property], databaseValues[property]))
                    .ForEach(property => tracking.Property(property).IsModified = false);
                    // Hereafter, SaveChanges executes UPDATE/DELETE for this entity, with refreshed values in WHERE clause.
                }
                break;
            }
            }
            return(tracking);
        }
示例#2
0
        public async Task <ServiceResult <CourseResponse> > UpdateCourse(CourseRequest request)
        {
            var courseEntity = Mapper.Map <CourseRequest, Course>(request);
            var modelState   = new Dictionary <string, string[]>();

            _unitOfWork.CourseRepository.Update(courseEntity);

            // Handle Conflicts here
            int result;

            if (request.ConflictStrategy == ResolveStrategy.ShowUnresolvedConflicts)
            {
                var resolveConflicts = ConcurrencyHelper.ResolveConflicts(courseEntity, modelState);
                result = await _unitOfWork.SaveAsync(resolveConflicts, userResolveConflict : true);
            }
            else
            {
                RefreshConflict refreshMode = (RefreshConflict)request.ConflictStrategy;
                if (!EnumExtensions.IsFlagDefined(refreshMode))
                {
                    refreshMode = RefreshConflict.StoreWins;
                }
                result = _unitOfWork.SaveSingleEntry(refreshMode);
            }
            return(await GetServiceResult(courseEntity, modelState, result));
        }
示例#3
0
        public int SaveMultipleEntries(RefreshConflict refreshMode, int retryCount = 3)
        {
            Action <IEnumerable <EntityEntry> > resolveConflicts = (entries) =>
            {
                (entries as List <EntityEntry>).ForEach(entry => entry.Refresh(refreshMode));
            };

            return(_context.SaveChangesAsync(resolveConflicts, retryCount).GetAwaiter().GetResult());
        }
示例#4
0
        public int SaveSingleEntry(RefreshConflict refreshMode, int retryCount = 3)
        {
            Action <IEnumerable <EntityEntry> > resolveConflicts = (entries) =>
            {
                entries.Single().Refresh(refreshMode);
            };

            return(_context.SaveChangesAsync(resolveConflicts, retryCount).GetAwaiter().GetResult());
        }
示例#5
0
        public static int SaveChanges(this DbContext context, RefreshConflict refreshMode, int retryCount = 3)
        {
            if (retryCount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(retryCount), $"{retryCount}必须大于0");
            }

            return(context.SaveChanges(
                       conflicts => conflicts.ToList().ForEach(tracking => tracking.Refresh(refreshMode)), retryCount));
        }
        public static DbEntityEntry Refresh(this DbEntityEntry tracking, RefreshConflict refreshMoode)
        {
            switch (refreshMoode)
            {
            case RefreshConflict.StoreWins:
            {
                //当实体被删除时,重新加载,设置追踪状态为Detached
                //当实体被更新时,重新加载,设置追踪状态为Unchanged
                tracking.Reload();
                break;
            }

            case RefreshConflict.ClientWins:
            {
                DbPropertyValues databaseValues = tracking.GetDatabaseValues();
                if (databaseValues == null)
                {
                    //当实体被删除时,设置追踪状态为Detached, 此时客户端无所谓获胜
                    tracking.State = EntityState.Detached;
                }
                else
                {
                    //当实体被更新时,刷新数据库原始值
                    tracking.OriginalValues.SetValues(databaseValues);
                }
                break;
            }

            case RefreshConflict.MergeClientAndStore:
            {
                DbPropertyValues databaseValues = tracking.GetDatabaseValues();
                if (databaseValues == null)
                {
                    //当实体被删除时,设置追踪状态为Detached, 当然此时客户端没有合并的数据,并设置追踪状态为Detached
                    tracking.State = EntityState.Detached;
                }
                else
                {
                    //当实体被更新时
                    DbPropertyValues originValues = tracking.OriginalValues.Clone();
                    tracking.OriginalValues.SetValues(databaseValues);

                    //如果数据库中对于属性有不同值,保留数据库中的值
                    databaseValues.PropertyNames.Where(property => !object.Equals(originValues[property], databaseValues[property]))
                    .ToList()
                    .ForEach(property => tracking.Property(property).IsModified = false);
                }
                break;
            }
            }
            return(tracking);
        }
示例#7
0
        public static DbEntityEntry Refresh(this DbEntityEntry tracking, RefreshConflict refreshMode)
        {
            switch (refreshMode)
            {
            case RefreshConflict.StoreWins:
                //当实体被删除时,重新加载,设置状态为Detached
                tracking.Reload();
                break;

            case RefreshConflict.ClientWins:
            {
                DbPropertyValues databaseValues = tracking.GetDatabaseValues();
                if (databaseValues == null)
                {
                    tracking.State = EntityState.Deleted;
                }
                else
                {
                    tracking.OriginalValues.SetValues(databaseValues);
                }
                break;
            }

            case RefreshConflict.MergeClientAndStore:
            {
                DbPropertyValues databaseValues = tracking.GetDatabaseValues();
                if (databaseValues == null)
                {
                    tracking.State = EntityState.Deleted;
                }
                else
                {
                    DbPropertyValues originalValues = tracking.OriginalValues.Clone();
                    tracking.OriginalValues.SetValues(databaseValues);
                    databaseValues.PropertyNames.Where(property => !object.Equals(originalValues[property], databaseValues[property])).ToList().ForEach(property => tracking.Property(property).IsModified = false);
                }
                break;
            }
            }
            return(tracking);
        }
示例#8
0
 public static int SaveChanges(
     this DbContext context, RefreshConflict refreshMode, RetryStrategy retryStrategy) =>
 context.SaveChanges(
     conflicts => conflicts.ToList().ForEach(tracking => tracking.Refresh(refreshMode)), retryStrategy);
示例#9
0
        public static EntityEntry Refresh(this EntityEntry tracking,
                                          RefreshConflict refreshMode)
        {
            switch (refreshMode)
            {
            case RefreshConflict.StoreWins:
            {
                //当实体被删除时,重新加载设置追踪状态为Detached
                //当实体被更新时,重新加载设置追踪状态为Unchanged
                tracking.Reload();
                break;
            }

            case RefreshConflict.ClientWins:
            {
                PropertyValues databaseValues = tracking.GetDatabaseValues();
                if (databaseValues == null)
                {
                    //当实体被删除时,设置追踪状态为Detached,当然此时客户端无所谓获胜
                    tracking.State = EntityState.Detached;
                }
                else
                {
                    //当实体被更新时,刷新数据库原始值
                    tracking.OriginalValues.SetValues(databaseValues);
                }
                break;
            }

            case RefreshConflict.MergeClientAndStore:
            {
                PropertyValues databaseValues = tracking.GetDatabaseValues();
                if (databaseValues == null)
                {
                    /*当实体被删除时,设置追踪状态为Detached,当然此时客户端没有合并的数据
                     * 并设置追踪状态为Detached
                     */
                    tracking.State = EntityState.Detached;
                }
                else
                {
                    //当实体被更新时,刷新数据库原始值
                    PropertyValues originalValues = tracking.OriginalValues.Clone();
                    tracking.OriginalValues.SetValues(databaseValues);
                    //如果数据库中对于属性有不同的值保留数据库中的值
#if SelfDefine
                    databaseValues.PropertyNames // Navigation properties are not included.
                    .Where(property => !object.Equals(originalValues[property], databaseValues[property]))
                    .ForEach(property => tracking.Property(property).IsModified = false);
#else
                    databaseValues.Properties
                    .Where(property => !object.Equals(originalValues[property.Name],
                                                      databaseValues[property.Name]))
                    .ToList()
                    .ForEach(property =>
                             tracking.Property(property.Name).IsModified = false);
#endif
                }
                break;
            }
            }
            return(tracking);
        }
示例#10
0
        public static async Task <EntityEntry> RefreshAsync(this EntityEntry tracking, RefreshConflict refreshMode)
        {
            switch (refreshMode)
            {
            case RefreshConflict.StoreWins:
                {
                    await tracking.ReloadAsync();

                    break;
                }

            case RefreshConflict.ClientWins:
                {
                    PropertyValues databaseValues = await tracking.GetDatabaseValuesAsync();

                    if (databaseValues == null)
                    {
                        tracking.State = EntityState.Detached;
                    }
                    else
                    {
                        tracking.OriginalValues.SetValues(databaseValues);
                    }
                    break;
                }

            case RefreshConflict.MergeClientAndStore:
                {
                    PropertyValues databaseValues = await tracking.GetDatabaseValuesAsync();

                    if (databaseValues == null)
                    {
                        tracking.State = EntityState.Detached;
                    }
                    else
                    {
                        PropertyValues originalValues = tracking.OriginalValues.Clone();
#if !EF
                        originalValues.SetValues(tracking.OriginalValues);
#endif
                        tracking.OriginalValues.SetValues(databaseValues);
#if EF
                        databaseValues.PropertyNames
                        .Where(property => !object.Equals(originalValues[property], databaseValues[property]))
                        .ForEach(property => tracking.Property(property).IsModified = false);
#else
                        databaseValues.Properties
                        .Where(property => !object.Equals(originalValues[property.Name], databaseValues[property.Name]))
                        .ForEach(property => tracking.Property(property.Name).IsModified = false);
#endif
                    }
                    break;
                }
            }
            return(tracking);
        }