Exemple #1
0
        public Summary UpdateSummary(Summary summary, User user, DbConcurencyUpdateOptions concurencyUpdateOption)
        {
            //Изменение значения поля ReadOnly осуществляеться другой операцией службы


            AuthenticateUser(user);

            bool canReadSummary = false;

            foreach (var g in user.UserGroups)
            {
                if (g.CanReadAccountablesSummary)
                {
                    canReadSummary = true;
                }
            }

            if (!canReadSummary)
            {
                throw new FaultException <AuthenticateFaultException>(new AuthenticateFaultException(user));
            }

            if (summary.CheckPeriodIsUnlocked() == false)
            {
                throw new FaultException <PeriodIsLockedException>(new PeriodIsLockedException(summary.SummaryDate));
            }

            //Пользователь который изменил данные устанавливается по факту
            if (summary.UserLastChanged == null || summary.UserLastChanged.Id != user.Id)
            {
                summary.UserLastChanged = user;
            }
            summary.SetAutoValues();

            Summary result = null;

            using (CFAPContext ctx = new CFAPContext())
            {
                ctx.Configuration.ProxyCreationEnabled = false;

                try
                {
                    //Группы пользователей уже существуют в сущности
                    //Если, по какой то причине их нет - будет исключение валидации

                    summary.SetRelationships(ctx);

                    //В данном случае AddOrUpdate не сработает в выдаче исключения оптимистичного паралелизма. Он перезагружет сущности в контекс и формирует уже актуальное поле RowVersion
                    ctx.Summaries.Attach(summary);

                    var summaryDbVersion = (Summary)ctx.Entry(summary).GetDatabaseValues().ToObject();
                    if (summaryDbVersion.ReadOnly)
                    {
                        throw new ReadOnlyException();
                    }

                    ctx.Entry(summary).State = EntityState.Modified;

                    //Ручной запуск валидации необходм так как при модификации данных связи с сущностями помечены как EntityState.Unchanged
                    //В итоге, без ручной валидации, при неверных данных или значениях null будет исключения при внесении данных в бд, а валидация EF ничего не заметит
                    summary.CustomValidate(ctx);

                    ctx.SaveChanges(concurencyUpdateOption);

                    result = (from s in ctx.Summaries where s.Id == summary.Id select s).Single();
                }
                catch (ReadOnlyException)
                {
                    throw new FaultException <TryChangeReadOnlyFiledException>(new TryChangeReadOnlyFiledException(typeof(Summary), summary.Id, null, user));
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    Summary dbSummary      = (Summary)ex.Entries.Single().GetDatabaseValues().ToObject();
                    Summary currentSummary = summary;

                    dbSummary = LoadRelationshipsDbSummary(dbSummary);

                    ConcurrencyException <Summary> concurrencyException = new ConcurrencyException <Summary>(dbSummary, currentSummary);
                    throw new FaultException <ConcurrencyException <Summary> >(concurrencyException);
                }
                catch (DbEntityValidationException ex)
                {
                    throw new FaultException <DataNotValidException>(new DataNotValidException(ex.EntityValidationErrors));
                }
                catch (NullReferenceException ex)
                {
                    throw new FaultException <FiledDeletedException>(new FiledDeletedException(ex));
                }
                catch (Exception ex)
                {
                    throw new FaultException <DbException>(new DbException(ex));
                }
            }


            return(result);
        }