我的页面a显示了标题记录以及详细记录列表。当用户点击Save时,我正在努力制作一种干净有效的插入/删除/更新详细记录的方法。
详细记录显示在jQuery DataTable中,每个详细记录后面的视图模型都有一个IsNew和IsRemoved属性。当用户添加详细记录时,其IsNew属性设置为true。当用户删除详细记录时,它将被软删除,并且其IsRemoved属性设置为true。
当用户点击“保存”并将页面发布到我的控制器时,我的逻辑现在看起来像这样
[HttpPost]
public ActionResult EditData(ViewModel viewModel)
{
// Update the record's header details here
// ...
foreach (var childViewModel in viewModel.Children)
{
// Use AutoMapper to map the view model to a model
MyChildRecord childModel = this.mapper.Map<MyChildRecord>(childViewModel);
if (childViewModel.IsNew)
{
this.context.MyChildRecords.Add(childModel);
}
else if (childViewModel.IsRemoved)
{
this.context.MyChildRecords.Attach(childModel);
this.context.MyChildRecords.Remove(childModel);
}
else
{
this.context.Entry(childModel).State = EntityState.Modified;
}
}
this.context.SaveChanges();
return RedirectToAction("EditData", new { id = viewModel.Id } );
}
我不喜欢这段代码的事情是,即使没有关于子记录的更改,我仍然在数据库中更新它。我能想出的唯一解决方案是
让每个视图模型存储其原始值的副本,然后在用户保存页面时将其当前值与其原始值进行比较。我不喜欢这个解决方案,因为我必须有一堆代码来存储原始值,然后我必须将原始值作为隐藏字段放在我的ASP页面上,以便它们在Web请求之间传递。 / p>
当用户保存页面时,让控制器遍历每个子视图模型,从数据库加载原始数据,并比较视图模型的当前值以查看是否需要更新行。我不喜欢这种方法,因为它涉及很多额外的字段比较代码,我仍然需要不必要地去数据库。
这似乎是一种常见的情况,因此必须有一种普遍接受的方法。我该怎么办呢?
答案 0 :(得分:1)
首先,考虑到额外的更新确实会产生额外的网络流量,但可能是您的实际数据库服务器足够聪明,如果没有任何更改,则不会对磁盘上的数据库执行任何操作。
其次,请考虑您的应用程序可能不是使用数据库表的唯一程序。当你看到它时,其他人可能已经改变了记录。为了安全起见,您确实需要两个解决方案:检查用户是否更改了表单,并检查数据库行是否与向用户显示数据时的数据库行相同。如果两者都已更改,通常会将其视为错误,并通知用户。