2012-02-01 78 views
2

我已经后它保存它刚刚得到了保存到数据库如何找出实体框架对象是否已更改?

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 

被称为Uczestnik对象的回ObjectListView其中用户决定改变一些值和值从多个改变(一个值是精确)。如果我检查值的实体状态它处于Unchanged状态,所以调用.Attach和.SaveChanges()将不会执行任何操作。我可以使用ChangeObjectState,但如果没有任何变化,那么没有意义。

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

我怎么能探测到这一变化,并防止不必要的流量(我能想象在那里没有在保存文件5MB大物体被改变的情况),所以resaving它没有任何意义。除非实体足够聪明,才能检测到只有一个字段从15更改并仅更改该字段?

+0

你看过ObjectContext.DetectChanges吗? – 2012-02-01 22:53:23

+0

不,不知道吗?我将如何使用它?同样考虑到在'using'中包含上下文,当它在新的上下文中执行时,DetectChanges不会显示任何内容吗? – MadBoy 2012-02-01 22:55:10

回答

3

如果您Detach实体它不被上下文跟踪。在这种情况下,您有责任检测对象何时发生变化,并通过使用ChangeObjectState告知上下文有关更改。所以你必须跟踪用户已经修改或直接实施的东西到你的实体。例如,执行INotifyPropertyChanged(如果您使用的是基于EntityObject的实体,则此接口应该已经实现)。

+0

您可以显示一个示例(或指向其中的一个链接)如何通知上下文,只有15列中的一个值发生了更改,因此更新不会触及其他14列? – MadBoy 2012-02-01 23:11:21

+1

检查[this](http://stackoverflow.com/questions/3729044/how-can-i-update-a-single-field-from-an-entity-with-entity-framework/3730581#3730581) – 2012-02-02 13:54:05

+0

谢谢。很有用。我看到一些关于自我追踪实体的文章,其中有些变化就像这个博客http://blogs.msdn.com/b/adonet/archive/2011/02/09/self-tracking-entities-original-values-and- update-customization.aspx你知道这是个好主意还是我应该用你的方式手工做? – MadBoy 2012-02-02 18:56:52

5

如果实体与上下文分离,除非您正在从数据库重新加载原始实体,或者您正在使用自我跟踪实体或自行管理跟踪,否则无法找出发生了什么变化。

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

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

此方法标志着其具有原始和拆卸实体之间不同的值作为修改的属性。 SaveChanges将创建一个只包含那些已更改属性的UPDATE语句。如果没有财产变更,SaveChanges什么都不做。

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

+0

谢谢,我想最好的方法是像@Ladislav Mrnka建议的那样实施跟踪。这个程序应该工作通过广域网链接和文件同步多次,可以是小500kb或大20MB可能是一个杀手,如果我决定从数据库重新加载它们。 – MadBoy 2012-02-01 23:13:27

相关问题