I've an object which is called
Uczestnik which just got saved to database
var konsultant = uczestnik.Konsultanci; uczestnik.Konsultanci = null; // null attached object and reuse it's ID later on for SAVE purposes uczestnik.KonsultantNazwa = konsultant.KonsultantNazwa; uczestnik.Szkolenie = null; // null attached object and reuse it's ID later on for SAVE purposes uczestnik.SzkolenieID = szkolenie.SzkolenieID; context.SzkolenieUczestnicies.AddObject(uczestnik); context.SaveChanges(); context.Detach(uczestnik); // detatch to prevent Context problems uczestnik.Szkolenie = szkolenie;// reassign for use in ObjectListView uczestnik.Konsultanci = konsultant; // reassign for use in ObjectListView
After it's saved it's back into ObjectListView where user decided to change some value and the value was changed (one value from multiple to be exact). If I check value's entity state it's in Unchanged state so calling .Attach and .SaveChanges() won't do anything. I can use
ChangeObjectState but if there's nothing changed then there's no sense to do so.
context.SzkolenieUczestnicies.Attach(uczestnik); //context.ObjectStateManager.ChangeObjectState(uczestnik, EntityState.Modified); context.SaveChanges();
How can I detect the change and prevent unnecessary traffic (I can imagine situation where nothing is changed in the object that holds files 5mb big) so
resaving it makes no sense. Unless Entity is smart enough to detect that only one field was changed from 15 and change only that field?
Detach entity it is not tracked by the context. In such case you are responsible for detecting when the object has changed and inform the context about changes by using
ChangeObjectState. So you must track what user has modified or implement something directly to your entities. For example implement
INotifyPropertyChanged (if you are using EntityObject based entities this interface should be already implemented).
If the entity is detached from a context you can't find out what has changed unless you are reloading the original entity from the database or you are using self-tracking entities or manage a tracking somehow yourself.
If you reload the entity you can use
var originalEntity = context.MyEntities.Single(e => e.Id == detachedEntity.Id); context.MyEntities.ApplyCurrentValues(detachedEntity); context.SaveChanges();
This method marks the properties as modified which have different values between original and detached entity.
SaveChanges will create an UPDATE statement which includes only those changed properties. If no property did change,
SaveChanges does nothing.
But you are not completely free from "unnecessary traffic" because you have to load the original entity, you will save an unnecessary UPDATE statement though.