我正在尝试找到一种可以实现的模式,以便快速允许使用Entity Framework对实体进行部分更新。当我拥有完整的对象时,我可以使用Attach,但如果我只进行部分更新,我想找到一种方法以可重复的方式执行它,而不是每次都指定更改的属性。
我找到了this idea,并且非常喜欢它,但我很难让“OriginalValues”和“CurrentValues”变得不同,它们总是匹配。我应该如何检索实体以使这样的更新方法起作用?
我检索数据并使用它来填充页面上的信息(但用户可以只更改/查看实体的一部分),所以我只返回回发后的部分实体信息 - 我是否必须检索并在更新之前分离实体?我不能使用Try / UpdateModel,因为我不是在控制器中做这项工作。任何想法或替代模式将不胜感激。
public virtual void Update(T entity, params Expression<Func<T, object>>[] updatedProperties)
{
//Ensure only modified fields are updated.
var dbEntityEntry = DbContext.Entry(entity);
if (updatedProperties.Any())
{
//update explicitly mentioned properties
foreach (var property in updatedProperties)
{
dbEntityEntry.Property(property).IsModified = true;
}
}
else
{
//no items mentioned, so find out the updated entries
foreach (var property in dbEntityEntry.OriginalValues.PropertyNames)
{
var original = dbEntityEntry.OriginalValues.GetValue<object>(property);
var current = dbEntityEntry.CurrentValues.GetValue<object>(property);
if (original != null && !original.Equals(current))
dbEntityEntry.Property(property).IsModified = true;
}
}
}
答案 0 :(得分:0)
看起来这可能是一个重复的问题。我找到了答案here。
要将更新的属性与数据库中的值进行比较,必须从数据库重新加载文档。一个例子:
public ActionResult Edit(Document document, bool sendEmail, string commentsTextBox)
{
if (ModelState.IsValid)
{
var documentInDB = docsDB.Documents.Single(d => d.Id == document.Id);
docsDB.Entry(documentInDB).CurrentValues.SetValues(document);
foreach (string propertyName in docsDB.Entry(documentInDB)
.OriginalValues.PropertyNames)
{
var OriginalValue = docsDB.Entry(documentInDB)
.OriginalValues.GetValue<object>(propertyName);
var NewValue = docsDB.Entry(documentInDB)
.CurrentValues.GetValue<object>(propertyName);
if (!OriginalValue.Equals(NewValue))
{
//capture the changes
}
}
}
}
显然,在我想要完成的业务层中实现,你必须将数据库版本和更新版本都传递给比较的方法。
一旦我测试过并且有一个工作样本,我就会更新代码。