例如:
public update(Person model) { // Here model is model return from form on post var oldobj = db.Person.where(x=>x.ID = model.ID).SingleOrDefault(); db.Entry(oldobj).CurrentValues.SetValues(model); }
它有效,但是,例如,
我的表中有50列但我在表单中只显示了25个字段(我需要部分更新我的表,其余25列保留相同的旧值)
我知道它可以通过“逐列映射”或通过为剩余的25列创建“隐藏字段”来实现.
只是想知道有没有优雅的方式来做到这一点,省力和最佳性能?
解决方法
因此,如果您只对对象更改1个字段然后调用SaveChanges(),则EF将仅在您调用SaveChanges()时更新该1字段.
这里的问题是,当您将视图模型映射到实体对象时,所有值都会被覆盖.这是我处理这个问题的方法:
在此示例中,您有一个名为Person的实体:
Person ====== Id - int FirstName - varchar Surname - varchar dob - smalldatetime
现在让我们说我们想要创建一个只更新dob的视图模型,并将所有其他字段保持原样,这就是我这样做的方式.
首先,创建一个视图模型:
public class PersondobVm { public int Id { get; set; } public DateTime dob { get; set; } public void MapToModel(Person p) { p.dob = dob; } }
现在大致如下编写代码(您必须更改它以匹配您的上下文名称等):
DataContext db = new DataContext(); Person p = db.People.FirstOrDefault(); // you would have this posted in,but we are creating it here just for illustration var vm = new PersondobVm { Id = p.Id,// the Id you want to update dob = new DateTime(2015,1,1) // the new dob for that row }; vm.MapToModel(p); db.SaveChanges();
在将视图模型字段分配给实体对象之前,MapToModel方法可能更复杂并且会执行各种其他检查.
exec sp_executesql N'UPDATE [dbo].[Person] SET [dob] = @0 WHERE ([Id] = @1) ',N'@0 datetime2(7),@1 int',@0='2015-01-01 00:00:00',@1=1
所以你可以清楚地看到,Entity Framework没有尝试更新任何其他字段 – 只是dob字段.
我知道在你的例子中你想避免手工编写每个作业,但我认为这是最好的方法.你把它全部收集在你的VM中,这样它就不会乱丢你的主代码,这样你就可以满足特定需求(即那里的复合类型,数据验证等).另一种选择是使用AutoMapper,但我不认为它们是安全的.如果您在VM中使用AutoMapper并将“dob”拼写为“Doob”,则不会将“Doob”映射到“dob”,也不会告诉您它!它会无声地失败,用户会认为一切正常,但更改不会被保存.
如果您在VM中将“dob”拼写为“Doob”,编译器将提醒您MapToModel()正在引用“dob”,但您的VM中只有一个名为“Doob”的属性.
我希望这可以帮助你.
原文地址:https://www.jb51.cc/aspnet/245197.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。