public void UpdateMovie(Movie movie) { using (var context = new DomainContext()) { //attach it context.Movies.Attach(movie); //mark it as modified context.Entry(movie).State = EntityState.Modified; //save - but saves all properties... context.SaveChanges(); } }The update property saves all the properties - but what if we only wanted to save certain properties? Like this:
update [dbo].[Movies]
set [BoxOffice] = @0
where ([Id] = @1)
The safest way is to do it manually (and you avoid mass assignment vulnerabilities). You have to reload the entity from the database.
public void UpdateMovieBoxOffice(Movie movie) { using (var context = new DomainContext()) { //get database version var databaseMovie = context.Movies.Find(movie.Id); //manually copy the values databaseMovie.BoxOffice = movie.BoxOffice; //save context.SaveChanges(); } }The UI may be able to track changes (IPropertyNotifyChanged or similar) and give the data service a list of the changed properties. If so, we can use the context.Entry to specify the modified properties. The SQL UPDATE statement will update only those properties.
public void UpdateMovieProperties(Movie movie, IList<string> propertyNames) { using (var context = new DomainContext()) { //attach it context.Movies.Attach(movie); //use the context entry DbEntityEntry<Movie> entry = context.Entry(movie); foreach (var propertyName in propertyNames) { //modify the specific property states only entry.Property(propertyName).IsModified = true; } //save context.SaveChanges(); } }The other way is to detect the changes by comparing them to the database. This is similar to the second method, but we use entry.GetDatabaseValues() to get the database values and then compare them. As only the changed properties are marked as modified, the UPDATE statement uses only those properties.
public void UpdateMovieChangedProperties(Movie movie) { using (var context = new DomainContext()) { //attach it context.Movies.Attach(movie); //use the context entry DbEntityEntry<Movie> entry = context.Entry(movie); //do a database call to get the state var databaseValues = entry.GetDatabaseValues(); foreach (var propertyName in databaseValues.PropertyNames) { //modify the specific property states only entry.Property(propertyName).IsModified = true; } //save context.SaveChanges(); } }We don't take account of Complex Properties here (the DbPropertyEntries can be nested).