EntityFramework SaveChanges() 抛出并发事务错误
EntityFramework SaveChanges() throws concurrent transaction error
在我的 MVC 应用程序中,我有一个页面从我的 POLICIES table 加载一条记录,然后在我的视图中使用它。然后我的视图在页面上显示该记录的数据,但是为了编辑记录数据,用户需要单击 "Edit Policy" 按钮,这将启动一个 jQuery UI 对话框编辑模式下的相同记录。我意识到我可以只允许他们从主视图对其进行编辑,但这不是我的客户想要的。
我遇到的问题是,当我在 jQuery UI 对话框中时,当我尝试保存记录时出现以下错误。
FirebirdSql.Data.FirebirdClient.FbException: lock conflict on no wait
transaction
我的对话框的控制器方法执行以下代码。 PolicyModel 只是一个 class,用作对话框的 ViewModel,而 Policy 属性 是表示 Policy table.
的对象
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.
}
要保存的对话框按钮只是使用 var formData = new FormData($('#myformid').get(0));
创建新的 FormData,然后我将其传递给我的保存控制器方法。
保存方法设置如下
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);
存档将正确更新。
这就像对话框视图持有资源或其他东西。有什么想法吗?
更新
作为参考,dbContext 的范围限定为控制器 class,我的 SavePolicy 方法位于其中,如下所示...
public class MainController : Controller {
private DBModel dbContext = new DBModel();
// other methods
public ActionResult SavePolicy(PolicyModel policyModel) {
// method code as see above
}
}
ASP.NET MVC 控制器通常有这个:
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
因此,如果您要在操作之外声明上下文,则应验证是否已实现此方法。
事实证明,在第一次执行时 (a select),您的上下文 keeps track of the record at Firebird and it is never disposed。第二次执行将再次尝试 select 相同的条目,该条目仍被另一个未正确处理的上下文跟踪。
在每个动作中使用范围上下文是另一种解决方法,但在我看来它有点麻烦。
在我的 MVC 应用程序中,我有一个页面从我的 POLICIES table 加载一条记录,然后在我的视图中使用它。然后我的视图在页面上显示该记录的数据,但是为了编辑记录数据,用户需要单击 "Edit Policy" 按钮,这将启动一个 jQuery UI 对话框编辑模式下的相同记录。我意识到我可以只允许他们从主视图对其进行编辑,但这不是我的客户想要的。
我遇到的问题是,当我在 jQuery UI 对话框中时,当我尝试保存记录时出现以下错误。
FirebirdSql.Data.FirebirdClient.FbException: lock conflict on no wait transaction
我的对话框的控制器方法执行以下代码。 PolicyModel 只是一个 class,用作对话框的 ViewModel,而 Policy 属性 是表示 Policy table.
的对象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.
}
要保存的对话框按钮只是使用 var formData = new FormData($('#myformid').get(0));
创建新的 FormData,然后我将其传递给我的保存控制器方法。
保存方法设置如下
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);
存档将正确更新。
这就像对话框视图持有资源或其他东西。有什么想法吗?
更新
作为参考,dbContext 的范围限定为控制器 class,我的 SavePolicy 方法位于其中,如下所示...
public class MainController : Controller {
private DBModel dbContext = new DBModel();
// other methods
public ActionResult SavePolicy(PolicyModel policyModel) {
// method code as see above
}
}
ASP.NET MVC 控制器通常有这个:
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
因此,如果您要在操作之外声明上下文,则应验证是否已实现此方法。
事实证明,在第一次执行时 (a select),您的上下文 keeps track of the record at Firebird and it is never disposed。第二次执行将再次尝试 select 相同的条目,该条目仍被另一个未正确处理的上下文跟踪。
在每个动作中使用范围上下文是另一种解决方法,但在我看来它有点麻烦。