我有一个用大约10个字段更新实体的表单,但是创建了这个特定表单只是为了更新三个字段。到目前为止我看到的所有示例都是在提交整个数据时使用SaveChanges()方法。提交部分数据会导致我的实体将所有其他字段替换为NULL。我找到的解决方案是在我的View页面上添加7个隐藏参数,但我很确定有更优雅的方法。 我是MVC4的新手,关于这个问题的任何教程都会非常有用。谢谢
我试过这个:
tblEmployee CurrentEmployee = model.EmployeeToDisplay;
try{
var ChosenEmployee = emp.SpecifiEmployee(Id);//retrieve selected employee
CurrentEmployee.IsNew = false;
CurrentEmployee.StatusID = 1;
ChosenEmployee.ShortId = CurrentEmployee.ShortId;
db.Entry(ChosenEmployee).State = EntityState.Modified;
db.SaveChanges();
}
tblEmployee CurrentEmployee = model.EmployeeToDisplay;
try{
var ChosenEmployee = emp.SpecifiEmployee(Id);//retrieve selected employee
CurrentEmployee.IsNew = false;
CurrentEmployee.StatusID = 1;
ChosenEmployee.ShortId = CurrentEmployee.ShortId;
db.Entry(ChosenEmployee).State = EntityState.Modified;
db.SaveChanges();
}
但是我收到了一个错误:
答案 0 :(得分:3)
您可以创建仅包含该表单中可编辑字段的视图模型。
然后在保存更改时,您需要从数据库中检索实体,将视图模型中的字段映射到检索到的实体,最后调用SaveChanges。
因此,给定实体FooEntity
,您可以创建仅包含要编辑的属性的视图模型EditFooViewModel
:
public class FooEntity
{
public int Id {get; set;}
public string Field1 {get; set;}
public string Field2 {get; set;}
public string NonEditableField1 {get; set;}
public string NonEditableField2 {get; set;}
}
public class EditFooViewModel
{
public int Id {get; set;}
public string Field1 {get; set;}
public string Field2 {get; set;}
}
然后,在提交表单时,检索实体并使用视图模型值更新它,然后再保存更改。保持示例简单,遵循此想法的控制器方法可能如下所示:
public ActionResult SaveChanges(EditFooViewModel viewModel)
{
... check model state for errors...
//Get the current entity value
var entity = dbContext.FooEntities.Single(e => e.Id == viewModel.Id);
//Map values from view model to entity
entity.Field1 = viewModel.Field1;
entity.Field2 = viewModel.Field2;
//Save changes
dbContext.SaveChanges();
...
}
编辑 - 我应该何时使用视图模型?
查看模型将帮助您将控制器/视图与业务层分离。 这意味着View模型可以提供业务对象的不同视图(在单个视图模型中组合多个实体,减少公开的属性或关注格式化数据!)并且它们将减少影响业务层上的更改将包含在控制器/视图上,反之亦然。 (从简单的更改,如将后端的属性重命名为更大的属性,如将业务层公开为其余的json服务)
它们还会阻止您将任何不需要的属性公开为隐藏字段,或者手动将可编辑属性设置为已修改(这与视图模型模式后面的映射代码非常相似!)。如果您有任何操作将实体作为json返回,也可以避免暴露整个业务对象。另一个好处是,当您忘记在EF(或您可能正在使用的其他后端)中手动附加和设置修改后的属性时,可以防止出现细微错误
确实,他们添加了一些自己的复杂性,主要是一组额外的类(视图模型)以及对视图模型 - 模型映射代码的需求。(尽管有一些工具可以在这里提供帮助,比如Automapper )
还要考虑到对于许多应用程序来说,将控制器/视图与后端分离是一项要求。在这些情况下,视图模型是可行的方法。
我还想说,在我看来,使用视图模型时添加的额外代码与替代方案相比并不算太多:
您可以决定对任何其他字段使用隐藏字段 参与验证(所以验证成功),然后附上 模型到EF上下文,手动设置可编辑属性 改性。您不需要视图模型类和映射代码,并且还可以防止在保存之前检索当前实体值的额外数据库命中。然而 您需要视图中的隐藏字段,以及设置每个字段的代码 在EF中修改的可编辑属性。不要忘记,如果有任何新的 验证时,您可能需要在视图中添加新的隐藏字段。
另一种选择是根本不使用隐藏字段,并在其中公开 仅查看实体中的可编辑字段。保存时,你 将需要从EF检索实体,手动映射可编辑 字段,最后验证并保存。这很漂亮 与使用视图模型非常相似,没有视图模型类。您 仍然需要从后端检索实体并映射 在验证和保存之前在视图中编辑的属性!虽然这个 在某些情况下可能就够了,在其他情况下你也需要 使用视图模型的好处。
然而,这并不意味着您应该盲目地在每个应用程序上使用视图模型。你是谁知道你的具体情况和要求,所以你需要考虑每个选择的优点和对比,并决定哪一个最有意义!
答案 1 :(得分:0)
来自EntityFramework的SaveChanges?
在调用saveChanges之前,您可能只需检索数据,并仅更新所需的字段。如果没有看到您的控制器或查看您如何获取/处理数据,很难给出准确的示例。
但我想它会是这样的。
...
var myEntity = dbContext.MyEntities.Single(i=> i.Id);
//update only the fields you want updated
dbContext.SaveChanges();