2011-08-13 46 views
5

期間未映射的屬性我有一個用戶模型,其中包含兩個[NotMapped]字符串屬性Password和ConfirmPassword。這些都是未映射的,因爲我將密碼保存爲字節數組(salting後),所以在用戶模型中有兩個額外的屬性(映射的)InternalPassword和Salt。如何防止EF驗證在DBContext.SaveChanges()

問題是,當我使用用戶模型更改密碼時,實體框架拋出DBEntityValidation錯誤,指出「密碼屬性是必需的」。我在這裏理解的是EF在保存之前試圖驗證我的模型,並且由於沒有設置Password/ConfirmPassword,它會拋出此錯誤。這提出了以下問題:

1)如果將密碼顯式註冊爲[NotMapped],爲什麼EF在保存期間驗證它? 2)如果EF在保存期間執行驗證,並且綁定期間也執行相同操作(控制器操作方法中的I.E.),它是否會影響性能? (驗證兩次) 3)解決此錯誤的建議方法是什麼? (如果我明確地將密碼屬性設置爲虛擬值,錯誤消失。)

編輯:我已經刪除了代碼,因爲它很冗長,可能是沒有答案的原因。如果有人想看看,我可以在下面添加它。

+0

這很奇怪,因爲即使'Password'屬性被映射,它也不會被默認需要,因爲'string'屬性從不需要,除非你明確指定 - 在屬性中放置'[Required]'屬性或調用'在Fluent API中使用IsRequired()'。你有'Password'屬性的設置嗎? – Slauma

+0

@Slauma是的,我需要在密碼上指定屬性。這需要在註冊期間提示用戶填寫密碼字段。但是因爲這沒有被映射,爲什麼EF在保存期間嘗試驗證它? –

回答

9

在EF自動驗證是某種奇怪的功能 - 我不喜歡它。你可以閱讀this article找到一些信息如何驗證剛剛選擇的屬性,但我希望你必須手動觸發驗證,並通過調用關閉全局驗證:

context.Configuration.ValidateOnSaveEnabled = false; 

您與NonMappedAttribute問題是有趣的。我並沒有深入實施EFv4.1中的驗證,但是如果實現是基於與基於數據註釋的常見驗證相同的規則構建的,則它僅使用從ValidationAttribute導出的屬性 - NotMappedAttribute不是從ValidationAttribute導出的。

這是這種實現的另一個問題 - 它結合了映射定義和驗證,但這兩個功能並不相同,不應該由同一個API實現。

@alun刪除了他的答案 - 您的問題的有效答案。您的驗證屬於根據用戶正在執行的操作查看模型。它不屬於持久性模型。爲什麼?完全是因爲你目前的問題 - 持久性模型只能容納單個驗證集,並且應用程序中的每個操作都必須確保滿足該集的驗證條件=即使當前操作不需要,您也必須確保填充了PasswordConfirmPassword它=>問題。

+0

我有不同的註冊模式和更改密碼。問題在於註冊模型(User)直接用這兩個額外的僅用於UI的字符串屬性來表示db表。我可以創建一個單獨的(查看)模型進行註冊,但這會導致重複和不必要地將註冊模型值複製到用戶模型中。 –

+0

我也發現並在此答案之前實施了ValidateOnSaveEnable,它似乎是目前唯一可見的解決方案。 –

+0

這不是重複。這是關注的分離。 –