如何确定实体框架对象是否已更改?

时间:2012-02-01 22:48:30

标签: c# winforms entity-framework

我有一个名为Uczestnik的对象,它刚刚保存到数据库

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   

保存之后,它返回到ObjectListView,用户决定更改某个值,并且值已更改(从多个值中确切地说是一个值)。如果我检查值的实体状态它处于Unchanged状态,那么调用.Attach和.SaveChanges()将不会做任何事情。我可以使用ChangeObjectState,但如果没有任何改变,那么就没有意义了。

context.SzkolenieUczestnicies.Attach(uczestnik);
//context.ObjectStateManager.ChangeObjectState(uczestnik, EntityState.Modified);
context.SaveChanges();

如何检测更改并防止不必要的流量(我可以想象在保存文件5mb大的对象中没有任何更改的情况)所以resaving没有意义。除非实体足够聪明,只能检测到只有一个字段从15更改并仅更改该字段?

2 个答案:

答案 0 :(得分:5)

如果实体与上下文分离,除非您从数据库重新加载原始实体,或者您正在使用自我跟踪实体或以某种方式管理跟踪,否则您无法找到已更改的内容。

如果您重新加载实体,可以使用ApplyCurrentValues

var originalEntity = context.MyEntities.Single(e => e.Id == detachedEntity.Id);
context.MyEntities.ApplyCurrentValues(detachedEntity);
context.SaveChanges();

此方法将属性标记为已修改,在原始实体和分离实体之间具有不同的值。 SaveChanges将创建一个UPDATE语句,该语句仅包含那些已更改的属性。如果没有属性发生变化,SaveChanges什么都不做。

但是你没有完全摆脱“不必要的流量”,因为你必须加载原始实体,你将保存不必要的UPDATE语句。

答案 1 :(得分:3)

如果您Detach实体未被上下文跟踪。在这种情况下,您负责检测对象何时发生更改,并使用ChangeObjectState通知上下文有关更改的信息。因此,您必须跟踪用户已修改或直接向您的实体实施的内容。例如,实现INotifyPropertyChanged(如果您使用的是基于EntityObject的实体,则应该已经实现了此接口)。