views:

72

answers:

3

I am using ASP.NET MVC and Entity Framework. I have an Edit Person web page where person's fields can be edited, then in the post back action, I use the following code.

var person = objectCtx.Persons.Where(s => s.Id == id).FirstOrDefault();
TryUpdateModel(person, form.ToValueProvider());
objectCtx.SaveChanges();

It works great. However in the generated SQL, I can still see an UPDATE statement even if the values have not been changed. Is there a way to avoid this in ASP.NET MVC or in Entity Framework?

A: 

You could simply not have it call SaveChanges() if the information is the same.

jchapa
But not all information is the same. User might change only onle field, but the Entity Framework is trying to update all the fields in the SQL.
Ian
@Ian and why is that a problem if it's the same data it's the same data
msarchet
The problem is the page may have several child entities. E.g., Person entity and Person.Address child entity. If the user only update the fields on the Person entity, just think we shouldn't update the Person.Address entity.
Ian
+2  A: 

Well, if you assign a property, then the Entity Framework will presume you know what you're doing and update it. You're saying that the user changed only one field, but I'm not sure how either MVC or the Entity Framework is supposed to know that, of all the keyvalue pairs in the POSTed HTML form, only one was actually changed by the user. You are saying, in your question, that "the values have not been changed," but in your comments on @jchapa's answer you say that "not all information is the same." This suggests that the actual issue is not with what the Entity Framework is doing, but rather what you are telling it to do.

I think that perhaps you are looking for a solution in the wrong place.

If your real problem is that the model passed to the action contains fields which the user can never change and which should never be updated (perhaps because they are not actually on the form at all), then you can pass a whitelist to TryUpdateModel.

If your real problem is that another user might have changed the Person instance between the time the user issued a GET request for the form and the time the user POSTed her changes, then you can add a TIMESTAMP field to the table and set fixed concurrency mode on it.

Craig Stuntz
A: 

What I want is something like this in the post back code:

if (person.CellPhone != form["CellPhone"])
{
  person.CellPhone = form["CellPhone"]
}

And do this for all the 20 fields in the Person entity, and any child entity such as Person.Address. I'm wondering if ASP.NET MVC can compare the original value before setting the entity's property in TryUpdateModel?

If it doesnt' make sense to do this in MVC code, looks like the other way is to have a custom T4 template to add this comparison in the property setter in the entity framework code generation. Here. I'm just wondering what's the right and easy way to do it.

Thanks.

Ian