有效且雄辩地插入/删除/更新子记录

时间:2017-08-03 18:04:35

标签: c# asp.net asp.net-mvc entity-framework ef-code-first

我的页面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 } );
}

我不喜欢这段代码的事情是,即使没有关于子记录的更改,我仍然在数据库中更新它。我能想出的唯一解决方案是

  1. 让每个视图模型存储其原始值的副本,然后在用户保存页面时将其当前值与其原始值进行比较。我不喜欢这个解决方案,因为我必须有一堆代码来存储原始值,然后我必须将原始值作为隐藏字段放在我的ASP页面上,以便它们在Web请求之间传递。 / p>

  2. 当用户保存页面时,让控制器遍历每个子视图模型,从数据库加载原始数据,并比较视图模型的当前值以查看是否需要更新行。我不喜欢这种方法,因为它涉及很多额外的字段比较代码,我仍然需要不必要地去数据库。

  3. 这似乎是一种常见的情况,因此必须有一种普遍接受的方法。我该怎么办呢?

1 个答案:

答案 0 :(得分:1)

首先,考虑到额外的更新确实会产生额外的网络流量,但可能是您的实际数据库服务器足够聪明,如果没有任何更改,则不会对磁盘​​上​​的数据库执行任何操作。

其次,请考虑您的应用程序可能不是使用数据库表的唯一程序。当你看到它时,其他人可能已经改变了记录。为了安全起见,您确实需要两个解决方案:检查用户是否更改了表单,并检查数据库行是否与向用户显示数据时的数据库行相同。如果两者都已更改,通常会将其视为错误,并通知用户。

相关问题