2011-04-20 35 views
17

我最近開始使用實體框架,它一直很痛苦的檢查,如果我真的需要新的記錄添加到數據庫或沒有。我要知道,因爲我在插入它之前做了一個查詢,如果它存在,那麼我保留該實例,因爲我需要使用它在一些關係中。在Entity Framework中,Add和Attach有什麼區別,我該如何解決我的問題?

讓我們假設我的實體名稱爲Book

問題是當一個實體是不是在數據庫中,和我做的:

Book b = //... 
modelContainer.AddToBooks(b); 

我可以很容易做到:

​​

每次我添加一個新的實體(不管是什麼實體它是),這將工作正常,因爲我一次插入一種條目,並檢查它是否已經在數據庫中,我不會有重複問題。

但是如果我想避免調用SaveChanges()如此頻繁?

在這個問題上:Is is possible to check if an object is already attached to a data context in Entity Framework?,問題的作者提供了一種方法一種,可以幫助我在我的情況,但如果我Add對象上下文,而不是Attaching它,它不工作。

我的問題(也許兩年,但非常相關的)是:加之間的區別是什麼和安裝,我怎麼能解決我的問題?

編輯:
這是我遇到的問題的一個例子。

我有一個實體Result與另外兩個實體有關係:TrainerHorse

我得到來自外部源的數據,所以我必須手動創建所有實體。

每次我需要插入一個新的Trainer,我做的:

var trainer = Trainer.CreateTrainer(Id) 

然後我查詢數據庫,看看是否與Id教練已經在數據庫上。如果是,那麼我將trainer變量替換爲數據庫中的變量。

如果不是的話,我可以在這裏做兩件事情:

  • 附上教練上下文(我可以檢查它是否已經存在使用該密鑰)
  • 教練加入上下文(使用AddToTrainers(...)

對於Horse的相同處理。

現在,當我需要創建一個新的Result(包含TrainerHorse),我以前的教練&馬分配到該結果的實例。

我應該怎麼做這裏可以添加到背景下,新Result

  • 如果我附上教練/馬,那麼當我附上結果時,我得到InvalidOperationException,讓我感到訓練師已經在對象上下文中。
  • 如果我添加的教練,而不是將其附着的,我得到另一個錯誤(不記得它的權利,但有人告訴我,一個教練已經在數據庫上)。

重要:
附接的結果時,給出第一誤差,以及做SaveChanges()當第二個。

我想避免此呼籲SaveChanges()每次我添加一個新的結果。

回答

21

ObjectContext內部跟蹤其或者通過上下文加載,連接或添加的所有實體。當SaveChanges被調用時,只有這些實體可以在數據庫中進行修改。每個這樣的實體都在ObjectStateManager一個ObjectStateEntryObjectStateEntry的主要屬性之一是State。狀態是枚舉類型EntityState它提供這些值:

  • 新增
  • 刪除
  • 獨立
  • 改性
  • 不變

從數據庫加載每個實體是在Unchanged州。分離是特殊狀態。你不會在ObjectStateManager分離狀態找到ObjectStateEntry。但是,如果您詢問ObjectStateManagerObjectStateEntry未被上下文跟蹤的實體,它將創建一個具有Detached狀態的新的ObjectStateEntry

現在AttachAddObject之間的區別:

  • Attach - 如果調用此方法ObjectContext將開始跟蹤整個對象圖(主要實體和所有相關實體)。所有尚未跟蹤的實體將被設置爲Unchanged狀態。
  • AddObject - 如果您調用此方法ObjectContext也將開始跟蹤整個對象圖(主要實體和所有相關實體)。區別在於所有尚未被跟蹤的實體將被設置爲Added狀態(=必須設置爲數據庫的新對象)。
+0

@Ladislav謝謝你的回答。根據我的問題,當我已經添加/附加了'B'的實例時,如何避免插入與'B'實例具有關係的實體'A'的實例?我只想插入'A'的實例,但我得到'InvalidOperationException' – 2011-04-20 08:01:48

+0

添加示例到您的問題。 – 2011-04-20 08:09:46

+0

@Ladislav已添加。 – 2011-04-20 19:07:09

8

我知道我有點遲到這篇文章,但正在尋找類似的解決方案...然後我發現這個微軟的文章,其可以簡潔地回答了大部分的OP的問題,並可能有助於將來讓觀衆?:

Add/Attach and Entity States ==(http://msdn.microsoft.com/en-us/data/jj592676.aspx

從文章:

這主題將介紹如何將實體添加和附加到上下文,以及Entity Framework在SaveChanges期間如何處理這些實體。

而具體看到頁面上的最後一節:

插入或更新模式:對於某些應用的常見模式是要麼添加實體如新(導致數據庫插入)或者將一個實體附加爲現有的,並根據主鍵的值將其標記爲已修改(導致數據庫更新)。