3

我仍然習慣於EF Code First,他花了數年時間與Ruby ORM ActiveRecord合作。 ActiveRecord以前有各種各樣的callbacks,比如before_validation和before_save,可以在將對象發送到數據層之前對其進行修改。我想知道在EF Code First對象建模中是否有等效技術。在使用EF Code-First模型保存或驗證之前執行邏輯

我知道如何在實例化時設置對象成員,當然,(設置默認值等),但有時您需要在對象生命週期的不同時刻進行干預。

使用稍微人爲的例子,說我有聯作者和一個連接表播放,相應地創作對象表示:

public class Authoring 
{ 
    public int ID { get; set; } 

    [Required] 
    public int Position { get; set; } 

    [Required] 
    public virtual Play Play { get; set; } 

    [Required] 
    public virtual Author Author { get; set; } 
} 

其中位置代表相關聯的所述作者的零索引排序給定播放。 (您可能會有兩個作者的單一「南太平洋」遊戲:位置爲0的「Rodgers」作者和位置爲1的「Hammerstein」作者。)

假設我想創建一個方法,在保存創作記錄之前,它會檢查是否存在與其關聯的Play的任何現有作者。如果否,則將位置設置爲0.如果是,則會發現設置與該播放關聯的最高值的位置並遞增1。

我在哪裏可以在EF代碼的第一個模型層中實現這樣的邏輯?而且,在其他情況下,如果在檢查驗證錯誤之前想要處理代碼中的數據,該怎麼辦?

基本上,我正在尋找一個相當於上面提到的Rails生命週期鉤子,或者至少有一些僞造它的方法。 :)

回答

3

您可以覆蓋DbContext.SaveChanges,做修復那裏並調用base.SaveChanges()。如果你這樣做,你可能想在修復之前調用DetectChanges。順便說一句。在編程實體框架DbContext書(ISBN 978-1-449-31296-1)第192-194頁中討論了同樣的問題。是的,這是在驗證的情況下...

3

您可以實施IValidatableObject。這給你一個鉤子:

IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 

而且你可以在那裏應用你的驗證邏輯。

還有SavingChanges事件ObjectContext(您可以從DbContext獲得)。

你可以只創建一個自定義IDoStuffOnSave接口,並將其應用到你的實體需要執行上節省一些邏輯(沒有什麼現成的)

+3

我會勸阻變化的實體驗證的幾個原因:1)如果你碰巧改變一個相關的實體,它不會被保存之前不處於修改狀態因爲DetectChanges在驗證後不會被再次調用,2)如果您更改已經驗證的相關實體,使其無效,則可以在將其保存到數據庫時發生異常3)這違反了單一責任原則。對於SavingChanges事件 - 再次,這是驗證發生後,所以你可以開槍自己的腳。 – Pawel 2012-03-23 23:36:03