In a console or Windows Forms app, it would be common to load an object from the database, work with it a bit, then save it. But with WebForms, the object was previously loaded and added to a page, and on the postback, you're getting a bunch of form fields & ViewState - the original object loaded from the db is gone, so you can't simply update a property and save the object.
When saving an object, I wouldn't normally select it from the database right away before saving. I would usually build a new object based on form values persisted through a postback and have the stored procedure update any fields that are editable by the user. But with Entity Framework, there is a lot of automatic work that happens when you load something from the database, update properties, then save it. It even automatically handles concurrency checks (assuming you have a Rowversion/Timestamp column set up.)
To best take advantage of Entity Framework's automatic handling of updated fields, select the object from database, set the properties you want to update (retrieved from form fields or ViewState), then call Context.SaveChanges(). If there are any changes, they will be saved.
Part of the magic is Optimistic Concurrency checking. Assuming you have saved the Rowversion in a form field or (easier) ViewState, you'll want to set that rowversion property in the object right before you save the changes. But setting MyObject.Rowversion =
What we have to do is overwrite the "original" rowversion value in the data we just retrieved - the one that will be compared against the database when it tries to do an update. This is how that is done:
ctx.Entry(objToUpdate).OriginalValues["rowversion"] = Rowversion;
Full example, where we are updating the Name and DOB properties of an object:
using (var ctx = new thingModel()) {
var objToUpdate = ctx.Things.SingleOrDefault(x => x.id == ID);
if (objToUpdate != null) {
// Update properties with user input from form
objToUpdate.name = Name; // Name property is bound to txtName.Text
objToUpdate.dob = DOB; // DOB property is bound to txtDOB.text
// Update original Rowversion with what was saved in Viewstate when data last loaded
ctx.Entry(objToUpdate).OriginalValues["rowversion"] = Rowversion; // Rowversion property is bound to ViewState["rowversion"]
// Save the changes
ctx.SaveChanges();
return true;
}
}
When the entity is being edited on an ASP.Net page, the simplest way to persist the originally-loaded rowversion is to store it in a page property bound to the ViewState. Set it and get it along with the other form data.
public Object RowVersion {
get {
return ViewState["RowVersion"];
}
set {
ViewState["RowVersion"] = value;
}
}