.Update () возвращает «Невозможно обновить столбец идентификаторов» - PullRequest
1 голос
/ 12 февраля 2020

На дисплее типа индекса есть ссылка, которая направляет управление на метод ниже. Статус ваучера обновляется до «Согласовано», после чего предпринимается попытка сохранения.

Похоже, что все выполняется так, как должно, до тех пор, пока не будет выполнено обновление / сохранение при получении исключения «Не удается обновить столбец идентификаторов».

В модели ваучеров нет навигационных свойств. Оба столбца идентификаторов хорошо вставляются при вставке.

Модель здесь:

public class Voucher
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public string VoucherId { get; set; }

        [Required]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Int64 VoucherNumber { get; set; }
        [Required]
        public string StudentId { get; set; }

        public string FullName { get; set; }

        [Required]
        public string VoucherType { get; set; }

        [Required]
        public DateTime VoucherCreateDate { get; set; }

        [Required]

        public string VoucherStatus { get; set; }
}

public ViewResult ReconcileVoucher(string id) //, Voucher voucher)
        {
            Voucher voucher = _context.Vouchers
                .Single(m => m.VoucherId == id);

            if (id != voucher.VoucherId)
            {
                ModelState.AddModelError("InputStatus", "Indicated Voucher is not present " + voucher.FullName);
                return View();
            }

            voucher.VoucherStatus = "Reconciled";

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(voucher);
                    _context.SaveChanges();
                    ModelState.AddModelError("InputStatus", "Voucher was Reconciled for " + voucher.FullName);
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    CreateLogRow("Reconcile Voucher", "testUser", "Concurrency exception for " + voucher.StudentId, ex.Message);
                    if (!VoucherExists(voucher.VoucherId))
                    {
                        ModelState.AddModelError("InputStatus", "The Voucher for " + voucher.FullName + " cannot be found");
                        return View();
                    }
                    else
                    {
                        throw;
                    }
                }
                CreateLogRow("Reconcile Voucher", "testUser", "Voucher was edited for " + voucher.StudentId + " -  " + voucher.FullName, null);
                return View();
            }
            return View(voucher);
        }

Ответы [ 2 ]

0 голосов
/ 13 февраля 2020

Когда вы выбираете объект из DbContext в свойстве call и update, вы не должны вызывать Update, а просто вызывать SaveChanges.

Т.е.

Voucher voucher = _context.Vouchers
    .Single(m => m.VoucherId == id);

// ...
voucher.VoucherStatus = "Reconciled";
// ...
_context.SaveChanges();

Update сгенерирует оператор, который обновит все столбцы на объекте, и хотя он должен исключать столбцы, помеченные как DatabaseGeneratedOption.Identity, здесь это может быть не так. Позволяя отслеживанию изменений делать свое дело без вызова Update, EF сгенерирует инструкцию UPDATE только для измененных столбцов.

Update будет более применимым при принятии сущности (как вы закомментировали) и присоединении / обновлении ее состояния в целом. Я не рекомендую этот подход, так как он перезаписывает все значения и уязвим для ряда проблем, включая устаревшие обновления данных, а также неожиданное вмешательство клиента. (Изменение столбцов, которые ваш пользовательский интерфейс не допускает атаками «человек в браузере» / «средний»). Лучше загрузить объект fre sh, проверить входящие данные, проверить версии строк / измененные временные метки для устаревших обновлений и т. Д. c , вместо того, чтобы принимать сущность по номиналу и помещать ее в БД.

Редактировать: Если эти идентификаторы являются GUID в БД, то почему бы не привести их в качестве GUID в сущности?

0 голосов
/ 13 февраля 2020

Вы помечаете все свойства как измененные, вызывая

 _context.Update(voucher);

Либо пропустите этот вызов и позвольте средству отслеживания изменений определить обновленные столбцы, либо явно пометьте свойство VoucherNumber как неизмененное.

db.Update(voucher);
db.Entry(voucher).Property(nameof(Voucher.VoucherNumber)).IsModified = false;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...