更新模型的优雅方式

时间:2013-09-14 22:37:16

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

假设我有一个拥有超过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
    }

2 个答案:

答案 0 :(得分:2)

请查看使用ViewModelAutoMapper之类的内容。 AutoMapper允许您使用域模型并使用基于约定的方法将它们转换为其他格式。例如。如果您的域模型上有一个名为Start的DateTime属性和一个名为Start的ViewModel字段,它将根据匹配的名称将您的域模型中的Start值复制到ViewModel中的Start。您可以执行更复杂的映射,例如在域模型中启动到ViewModel中的StartYear等。

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

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

您可以看到它的摘要here。这个Stack question和答案也说明了技术

答案 1 :(得分:1)

您应该使用一个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)。