3

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?

MadBoy
  • 10,824
  • 24
  • 95
  • 156
  • Have you looked at ObjectContext.DetectChanges? – Aaron McIver Feb 01 '12 at 22:53
  • No, wasn't aware of it? How would I use it? Also considering that context is enclosed in `using` wouldn't DetectChanges show nothing when it's executed on new context? – MadBoy Feb 01 '12 at 22:55

2 Answers2

6

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 ApplyCurrentValues:

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.

Slauma
  • 175,098
  • 59
  • 401
  • 420
  • Thanks, I guess the best way is to implement tracking like @Ladislav Mrnka suggested. This program is supposed to work thru WAN link and having Documents synchronized multiple times which can be small 500kb or large 20MB may be a killer if I decide to reload them from db. – MadBoy Feb 01 '12 at 23:13
3

If you 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).

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Can you show an example (or a link to one) how to inform context that only one value from 15 columns have changed so the update doesn't touch other 14 columns ? – MadBoy Feb 01 '12 at 23:11
  • 1
    Check [this](http://stackoverflow.com/questions/3729044/how-can-i-update-a-single-field-from-an-entity-with-entity-framework/3730581#3730581) – Ladislav Mrnka Feb 02 '12 at 13:54
  • Thanks. Very useful. I saw some article about self-tracking entities with some changes like on this blog http://blogs.msdn.com/b/adonet/archive/2011/02/09/self-tracking-entities-original-values-and-update-customization.aspx Do you know if it's good idea or should I do it by hand using your way? – MadBoy Feb 02 '12 at 18:56