与正常情况不同,我有实际有效的代码,但我想知道这是否是唯一的(或最好的方法)。
基本想法是我有一个现有的应用程序,它将手工制作的数据层移植到 Entity Framework 。作为最小化代码更改的折衷方案,我正在使用现有方法,这些方法往往采用更加断开连接的方法。例如我有很多这样的东西:
UpdateNote(int noteId, string note)
我似乎有一种适用于此类更新的方法,无需重新获取:
var context = new MyEntities();
context.Configuration.ValidateOnSaveEnabled = false;
var note = new Model.Note{ Id = noteId, Note = ""};
context.Notes.Attach(note);
note.Note = "Some Note";
context.SaveChanges();
有点难看(虽然足够简洁),所以我想知道是否有更好的方法来使用 EF?除了失去内置验证之外,这种方法还有什么缺点吗?
这是一种将在我的应用程序中使用的模式。
最佳答案
以下 DbContext 扩展方法是一种避免使用与您想要更改的值不同的值来初始化实体的方法。
public static class EFExtensions
{
public static void MarkAsModified(this DbContext context, object entity,
params string[] properties)
{
foreach (var property in properties)
context.Entry(entity).Property(property).IsModified = true;
}
}
然后您可以这样使用它:
var context = new MyEntities();
context.Configuration.ValidateOnSaveEnabled = false;
var note = new Model.Note { Id = noteId }; // only key properties required to set
note.Note = "Some Note";
note.SomeOtherProperty = 1234;
note.AndAnotherProperty = "XYZ";
context.Notes.Attach(note);
context.MarkAsModified(note, "Note", "SomeOtherProperty" , "AndAnotherProperty");
context.SaveChanges();
注意:这仅适用于标量属性,不适用于导航属性。
除了验证之外,我可以想象这种方法对于正确的并发检查来说是有问题的。
编辑
根据 @Adam Tuliper 下面的评论,并发可能不是问题,因为当实体手动附加到上下文(不从数据库中读取)并标记为已修改以将 UPDATE 命令发送到数据库。它只是覆盖数据库中的最新版本。感谢 Adam 指出了这一点!
关于asp.net - Entity Framework : Update single field with detached entity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7261998/