2012-02-23 61 views
0

作为实体框架代码的一些测试的一部分首先,我正在测试更改跟踪。在一个小的测试数据库中,我有一个表两辆车,我对运行一个测试方法:EF为什么在SaveChanges上读取我的Unchanged对象?

Debug.WriteLine("Reading cars..."); 
var cars = context.Cars.ToArray(); 
Debug.WriteLine("Updating top speed of first car..."); 
Debug.WriteLine(string.Format("Type of car[0] is {0}", cars[0].GetType().ToString())); 
cars[0].TopSpeed = 260; 

Debug.WriteLine("Saving changes..."); 
context.SaveChanges(); 

我已经添加了跟踪输出到Car类的TopSpeedBrand属性的getter和setter看他们如何访问。 TopSpeedint?BrandBrand实体的导航属性。运行上面的代码给出下面的输出。

 
Reading cars... 
Setting TopSpeed to 210 for ABC123. 
Car: Getting TopSpeed for ABC123. 
Setting TopSpeed to 250 for XYZ987. 
Car: Getting TopSpeed for XYZ987. 
Updating top speed of the first car... 
Type of car[0] is System.Data.Entity.DynamicProxies.Car_18E3E11297DC48759312BDF1C2FFEBE9F19BAE5D487CED2A9781A6CA730071EA 
Setting TopSpeed to 260 for ABC123. 
Saving changes... 
Car: Getting Brand for ABC123. 
Car: Getting Brand for XYZ987. 
Car: Getting TopSpeed for ABC123. 
Car: Getting TopSpeed for ABC123. 
Car: Getting TopSpeed for XYZ987. 
Car: Getting TopSpeed for ABC123. 
Car: Getting TopSpeed for ABC123. 
Car: Getting TopSpeed for ABC123. 
Car: Getting TopSpeed for ABC123. 
Car: Getting TopSpeed for ABC123. 

该对象的类型是用于更改跟踪的EF动态代理。当调用SaveChanges()时,读取未更改的XYZ987汽车的属性。我认为更改跟踪会导致EF只读取已知会更改的对象,或者我错过了某些内容?是否还需要添加其他功能才能启用更改跟踪?

回答

3

即使换一换跟踪代理的所有要求被满足,EF依旧采用了自动更改跟踪,除非明确地关闭:

context.Configuration.AutoDetectChangesEnabled = false; 

AutoDetectChangesEnabled文档是令人困惑:

真要是自动检测配置中的更改为启用 ;否则,是错误的。

看看ADO.NET的blog他们解释正确。

2

要启用动态更改跟踪,您需要使所有标量(非导航)属性变为虚拟。

3

在.NET 4上运行的EF 4.1,4.2和4.3中存在一个错误(或更确切地说,缺少优化),这会导致DetectChanges处理应该知道不需要更改跟踪的实体。这是因为运行在.NET 4上的EF不会跟踪是否有任何需要更改跟踪的实体,因此它必须检查每次。

当在.NET 4.5上运行时,它在EF5上是固定的,它现在即将推出。我刚刚使用.NET 4.5上的EF5验证了SaveChanges中未调用未​​更改的变更跟踪代理的属性的getter,即使将AutoDetectChangesEnabled设置为true也是如此。

即使在EF 4.1-4.3上,我也不认为应该调用getter,如果所有EF正在执行的是检查实体是否为更改跟踪代理,那么看起来好像可能存在另一个bug在这里。