Reputation: 7341
I have page a that shows a header record along with a list of detail records. I'm struggling with making a clean and efficient way of inserting/deleting/updating detail records when the user clicks Save.
The detail records are shown in a jQuery DataTable, and the view model behind each detail record has an IsNew and IsRemoved property. When the user adds a detail record, its IsNew property is set to true. When the user removes a detail record, it is soft-deleted and its IsRemoved property is set to true.
When the user clicks Save and posts the page to my controller, my logic right now looks like this
[HttpPost]
public ActionResult EditData(ViewModel viewModel)
{
// Update the record's header details here
// ...
foreach (var childViewModel in viewModel.Children)
{
// Use AutoMapper to map the view model to a model
MyChildRecord childModel = this.mapper.Map<MyChildRecord>(childViewModel);
if (childViewModel.IsNew)
{
this.context.MyChildRecords.Add(childModel);
}
else if (childViewModel.IsRemoved)
{
this.context.MyChildRecords.Attach(childModel);
this.context.MyChildRecords.Remove(childModel);
}
else
{
this.context.Entry(childModel).State = EntityState.Modified;
}
}
this.context.SaveChanges();
return RedirectToAction("EditData", new { id = viewModel.Id } );
}
The thing I don't like about this code is that even if nothing about a child record is changed, I'm still updating it in the database. The only solutions I can come up with to prevent that are
Have each view model store a copy of its original values and then compare its current value to its original values when the user saves the page. I don't like this solution because I'll have to have a bunch of code to store the original values, and then I have to put the original values as hidden fields on my ASP page so that they get carried between web requests.
When the user saves the page, have the controller iterate through each child view model, load the original data from the database, and compare the view model's current values to see if the row needs to be updated or not. I don't like this method because it involves a lot of extra code for the field comparison, and I still have to make unncessary trips to the database.
This seems like a common scenario so there must be a commonly accepted way of doing this. How should I be going about this?
Upvotes: 1
Views: 179
Reputation: 6255
First, consider that while the extra updates do incur additional network traffic, the likelihood is that your actual database server is smart enough not to actually do anything to the database on disk if nothing changed.
Secondly, consider that your application might not be the only program working with your database table. Somebody else might have changed the record while you were looking at it. To be safe, you really need both solutions together: check whether the user changed your form, AND check whether the database row is the same as it was when you got the data to show to the user. If both have changed, usually it is considered an error and the user is notified.
Upvotes: 1