【问题标题】:Efficiently and Eloquently Inserting/Deleting/Updating Child Records有效而雄辩地插入/删除/更新子记录
【发布时间】:2018-01-11 11:48:07
【问题描述】:

我的页面 a 显示了标题记录以及详细记录列表。当用户单击“保存”时,我正在努力寻找一种干净有效的方式来插入/删除/更新详细记录。

详细记录显示在一个 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 请求之间传递。

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

这似乎是一种常见的情况,因此必须有一种普遍接受的方式来执行此操作。我该怎么办?

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 您建议我如何进行逐个字段的比较?我担心随着应用程序的增长,编写每个字段的比较非常耗时,并且由于程序员可能忘记将它们添加到比较方法或忘记添加额外的字段被添加到预先存在的类中,因此也容易出错它们作为 ASP 页的隐藏字段。我可以通过使用反射制作比较函数来解决手动比较问题,但是仍然存在 ASP 隐藏字段问题。如果这是唯一的方法,那就这样吧;我只是希望有更好的东西。
    • 数据库端通常的解决方案是使用 ORM 框架,例如 NHibernate、LINQ to SQL 或 Microsoft 的 Entity Framework 或类似的东西,而不是直接使用 SQL。这样的框架会在编译时自动生成冗长乏味的检查代码。
    • 我在 UI 方面并没有那么多,但我相信 MVC - Model-View-Controller - 有相关的概念来检测回发时哪些字段发生了变化。真的归结为,你自己做的太多了。了解行业标准解决方案并加以使用。
    • 我正在使用实体框架,但我不确定这如何解决将所有视图模型字段与模型字段进行比较的问题,或者解决关于有一堆隐藏的 ASP 字段的问题这页纸。难道我还得有一堆支票,比如if (viewModel.FirstName != model.FirstName || viewModel.LastName != model.LastName || ...
    • 我想我对你的问题既不了解,又不知所措。我道歉。也许我应该删除这个答案;你绝对应该不赞成它,因为它没有回答你。
    猜你喜欢
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 2018-10-22
    • 2013-09-26
    • 1970-01-01
    相关资源
    最近更新 更多