2013-03-11 50 views
9

我讀過很多關於實體框架的文章(article1,article2),它多次調用DetectChanges,這使得它在處理大量數據時非常緩慢。EF Code First:很適合在SaveChanges之前調用DetectChanges?

例如,我可以在我初始化上下文時禁用autoDetectChanges,並且在致電.SaveChanges()之前調用DetectChanges()

上下文是否會識別插入/更改/刪除的實體?

var _dbContext = new ProjectContext(); 
_dbContext.Configuration.AutoDetectChangesEnabled = false; 

// add/edit/delete entities 

_dbContext.ChangeTracker.DetectChanges(); 
_dbContext.SaveChanges(); 

這種方法應該工作嗎?或者它可能會創建隱藏的錯誤?

+0

不是100%確定它是否在背景中有任何奇怪的現象,但我一直在使用類似的方法,但沒有發現任何不良副作用 – Thewads 2013-03-11 16:05:15

回答

16

Arthur Vickers定義規則時DetectChanges並不需要被調用(即使不是之前SaveChangesin this blog post

到EF代碼沒有呼叫將離開上下文在 DetectChanges需要被調用的狀態如果之前不需要叫 。

關於添加刪除這些都是「EF代碼」的方法,因爲你要麼打電話AddDelete或您的context.Entry(entity).State狀態設置爲AddedDeleted。所以,如果你只是循環訪問一系列實體並添加或刪除它們,那麼根本不需要撥打DetectChanges

關於編輯我相信,它有點微妙。當您通過使用更新的實體...

context.Entry(entity).CurrentValues.SetValues(someObject); 

...或使用的DbContext財產API ...

context.Entry(entity).Property(e => e.SomeProperty).CurrentValue = someValue; 

...那麼你不需要DetectChanges(甚至不在SaveChanges之前),因爲這些都是再次調用「EF代碼」。

如果你只需要改變一個實體的一樣屬性值...

entity.SomeProperty = someValue; 

...然後上面鏈接的第二條規則in the same blog post適用:

任何時間,非EF代碼更改可能需要調用一個實體的任何屬性值或 複雜對象。然後可能需要調用DetectChanges。

而且我覺得你其實需要DetectChangesSaveChanges如果你只是遍歷一些實體只有一個單呼,它們加載到或將它們連接到上下文和改變一些(標量和複雜)屬性值。

如果你做更復雜的東西(也許關係改變?或其他?)你的方法可能不是安全了,因爲

  1. AutoDetectChanges不會在它的方式來實現,並呼籲在許多EF方法是否會SaveChanges

  2. 是之前提到的是隻有一次正確的必要in the same blog post再次證明

    如果代碼使改變而改變對實體 的屬性,而不是隻調用添加或附加,然後,由規則2,DetectChanges 將需要被調用,至少作爲SaveChanges 的一部分並且還可能在之前也可以調用 。

    (從我高亮)

不幸的是我不知道的代碼在早期階段進行比對之前SaveChanges需要調用DetectChanges時,將顯示一個例子。但是因爲上面的第一點,我相信這樣的例子存在。

+0

這是一篇很棒的文章,謝謝。但我有點不清楚(對不起):1.爲什麼EF在實際保存到數據庫之前需要調用DetectChanges很多次才調用DetectChanges? 2.我正在使用具有普通屬性的'POCO'對象(未用'virtual'標記)。當我更改對象屬性值時,EF是否靜靜地調用DetectChanges()? – Catalin 2013-03-12 07:31:01

+0

@RaraituL:第1點:我不知道。這就是我最後一句話的意思。第2點:不。​​當您分配屬性值時,'SaveChanges'和其他一些EF方法稍後會調用'DetectChanges'。 'DetectChanges'將當前屬性值與原始值(在對象上下文中作爲「快照」存儲)進行比較,如果值更改,屬性將被標記爲已修改。它被稱爲「基於快照的更改跟蹤」。 – Slauma 2013-03-12 12:08:31

-2

可以通過DetectChanges解決的主要問題之一是當我們擁有ManyToMany關係和AutoDetectChanges=false關係時,EF中的數據持久存在。