更新模型的优雅方式

本文关键字:方式 模型 更新 | 更新日期: 2023-09-27 18:31:23

假设我有一个具有20多个属性的模型。

其中一些可以由用户在视图中编辑,但是出于安全原因,密码等数据不会保存在隐藏字段中,因此当我将视图模型发布到控制器时,某些属性为空

如何在不编写太多代码的情况下检查哪些属性发生了变化?

坏主意:

    [HttpPost]
    public ActionResult Edit(BigModel model)
    {
        BigModel old=db.Get(new.id);
        if(model.Property1 !=null && old.Property1 != model.Property1) old.Property1=model.Property1
        if(model.Property2 !=null && old.Property2 != model.Property2) old.Property2=model.Property2
        if(model.Property3 !=null && old.Property3 != model.Property3) old.Property2=model.Property2
        ...
        if(model.Property20 !=null && old.Property20 != model.Property20) old.Property20=model.Property20
    }

更新模型的优雅方式

看看如何使用ViewModel和AutoMapper之类的东西。自动映射器允许您采用域模型,并使用基于约定的方法将它们转换为其他格式。例如,如果您的域模型上有一个名为"开始"的 DateTime 属性和一个名为"开始"的 ViewModel 字段,则只会根据名称匹配将域模型中的"开始"值复制到 ViewModel 中的"开始"。您可以执行更复杂的映射,例如在域模型中开始到在视图模型中开始等。

ViewModel 应包含显示字段和要发布的字段(可能作为子编辑模型)。然后回发到编辑模型。

编辑模型将仅包含要更新的字段。然后,可以将其映射回域模型或手动完成。

您可以在此处查看其摘要。此堆栈问题和答案也说明了该技术

您应该使用具有视图上确切字段(非敏感字段)的视图模型,然后调用TryUpdateModel(old)运行时会将视图模型中的字段映射到模型,并且您不必担心字段不会更改。如果值相同,EF 不会将它们标记为已更改。

  [HttpPost]
    public ActionResult Edit(BigViewModel model)
    {
        BigModel old=db.Get(new.id);
        UpdateModel(old);
        //db.SaveChanges();
    }

您可能希望投资探查器,以查看发送查询时EF正在做什么以及它正在生成什么sql.您可以尝试ORM探查器或EFProf ...如果你不关心付费工具,你可以试试Glimpse(Glimpse.EF)。