EntityFramework SaveChanges () генерирует ошибку параллельной транзакции - PullRequest
0 голосов
/ 21 февраля 2019

В моем приложении MVC у меня есть страница, которая загружает запись из моей таблицы POLICIES и затем использует ее в моем представлении.My View затем отображает данные из этой записи на странице, однако для редактирования данных записи пользователю необходимо нажать кнопку «Редактировать политику», которая запускает диалоговое окно jQuery UI с той же записью в режиме EDIT.Я понимаю, что могу просто позволить им редактировать его из основного представления, однако это не то, чего хочет мой клиент.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я в диалоге jQuery UI, я получаюошибка ниже, когда я пытаюсь сохранить запись.

FirebirdSql.Data.FirebirdClient.FbException: блокировка конфликта при транзакции без ожидания

Выполнен метод Controller для моего диалогового окнаследующий код.PolicyModel - это просто класс, который служит ViewModel для диалогового окна, а свойство Policy - это объект, представляющий таблицу Policy.

public ActionResult Policy(int policyNo) {
     PolicyModel policyModel = new PolicyModel();
     policyModel.Policy = dbContext.POLICIES.FirstOrDefault(db => db.POLICY_NO == policyNo);
     return View(policyModel);
}

В представлении «Policy» я делаю стандартную форму, используя:

@using (Html.BeingForm("SavePolicy", "MyController", FormMethod.Post)) {
    //hidden element for policyNo created with @Html.HiddenFor
    //form elements here created using the @Html.TextBoxFor..etc.
}

Диалоговая кнопка для сохранения просто создает новые FormData с var formData = new FormData($('#myformid').get(0)); Затем я передаю их в свой метод контроллера сохранения.

Метод Save настраивается следующим образом

public ActionResult SavePolicy(PolicyModel policyModel) {

     var policy = dbContext.POLICIES.FirstOrDefault(db => db.POLICY_NO == policyModel.POLICY_NO);

     if (TryUpdateModel(policy,"Policy", updateFields.ToArray())) {
         dbContext.Entry(policy).State = EntityState.Modified;
         dbContext.SaveChanges();
     }

     return Json( new { result = 1, JsonRequestBehavior.AllowGet } );

}

Если я вручную изменю POLICY_NO, хотя на ЛЮБОЙ другой номер политики, кроме того, который в данный момент активен в диалоговом окне, как этот ...

var policy = dbContext.POLICIES.FirstOrDefault(db => db.POLICY_NO == 12345);

Сохранение будет обновлено правильно.

Это похоже на то, как диалоговое окно View удерживает ресурс или что-то в этом роде.есть идеи?

ОБНОВЛЕНИЕ

Для справки, dbContext ограничен классом Controller, в котором мой метод SavePolicy живет, как показано ниже ...

public class MainController : Controller {
     private DBModel dbContext = new DBModel();

     // other methods

     public ActionResult SavePolicy(PolicyModel policyModel) {

          // method code as see above

     }

}

1 Ответ

0 голосов
/ 23 февраля 2019

ASP.NET MVC Контроллеры обычно имеют следующее:

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        db.Dispose();
    }
    base.Dispose(disposing);
}

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

Оказывается, что при первом выполнении (выбор) ваш контекст отслеживает запись в Firebird и никогда не удаляется .Второе выполнение попытается снова выбрать ту же запись, которая все еще отслеживается другим контекстом, который не был правильно расположен.

Использование контекстного контекста внутри каждого действия - это еще один способ решения, но с моей точки зрения это немного более громоздко.

...