2012-02-23 58 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在這裏。