I'm trying to find a pattern that I can implement to quickly allow partial updates to entities using Entity Framework. I can use Attach when I have the full object, but if I'm only doing a partial update, I'd like to find a way to do it in a repeatable manner without specifying the changed properties every time.
I found this idea , and really like it, but I'm struggling to get the "OriginalValues" and "CurrentValues" to be different, they always match. How should I be retrieving entities in order for an update method like this to work?
I retrieve the data and use it to populate information on a page (but the user can change/view only part of the entity), so I only get back partial entity information on the post-back - do I have to retrieve and detach the entity before updating like this? I can't use Try/UpdateModel because I'm not doing this work in a controller. Any ideas or alternate patterns would be appreciated.
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;
}
}
}
It looks like this may have been a duplicate question. I found an answer here .
For the comparison of the updated properties with the values in the database you must reload the document from the database. One example:
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
}
}
}
}
Obviously to implement in a business layer like I was trying to accomplish, you'd have to pass both the database version and the updated version into the method that compares.
I'll update the code once I've tested and have a working sample.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.