2011-11-11 113 views
0

給定像Person這樣的簡單類,並帶有FirstName,LastName和DOB屬性以及Id屬性(它是主鍵)。如何防止首先使用EF代碼的邏輯重複?

當我調用我的create action時,我想執行驗證以確定我傳入的模型是否與FirstName,LastName和DOB屬性恰好匹配任何已存在的記錄。在這種情況下,我想排除Id屬性,因爲進入應用程序的模型還沒有,並會產生誤報。

目前我只是用任何擴展方法是這樣的...

if (!context.People.Any(x => x.FirstName == model.FirstName && x.LastName == 
model.LastName && x.DOB == model.DOB)) 

這肯定的作品,但完全是,好了,不優雅。

當然有更好的方法嗎?

+0

您可能可以通過對數據庫進行唯一約束來避免這種情況,然後在代碼中進行適當的錯誤處理。如果你想在值持久化之前檢查重複項,那麼我認爲'Any()',雖然不完全優雅,但是完全沒問題。 –

+0

[最好的方法來檢查對象是否存在於實體框架?](http://stackoverflow.com/questions/1802286/best-way-to-check-if-object-exists-in-entity-framework) –

+0

這不是重複的,你引用的問題的答案是我說我明確想避免的東西 – keithwarren7

回答

0

問題是你不希望直接在控制器中看到任何呼叫,或者你根本不喜歡該呼叫?

如果是前者,則使用驗證框架來隱藏控制器的詳細信息。如果是後者,則可以在數據庫中創建某種存儲過程/函數,然後調用它。

雖然我並不認爲這段代碼是壞的。我只是認爲它需要一個驗證。 FluentValidation對此非常好,但DataAnnotations也可以。

+0

我想真正的問題是,對Any的調用取決於在每個情況下寫出每個非關鍵屬性實體,而不是一個通用的調用。我想現在我可能會寫一個擴展方法,它接受一個模型並匹配非關鍵屬性的值。 所以底線,我可以問這個問題 - '我怎麼能比這更懶惰...' – keithwarren7

+0

寫這個擴展方法正是我正在努力回答你的問題。這似乎是最好的解決方案。你怎麼能更懶惰?問問它,看看其他人是否會爲你編寫它) – Sorax

+1

@ keithwarren7 - 擴展方法將是一個壞主意,因爲擴展方法是靜態的。您不希望在擴展方法中查詢數據庫,因爲它會在程序的整個生命週期中保持開放連接。 –

1

如果唯一性是一個業務需求,那麼你應該在數據庫中處理這個唯一的約束。然後,你不需要檢查,數據庫會拋出一個異常,並告訴你它何時被違反。您處理異常並告訴用戶他們已經在系統中。

+0

我不同意這種做法。我認爲使用驗證器會更好。除了驗證之外,您還可以擁有一個唯一的約束條件,但不應該期望發生這樣的異常。只是我的意見,但。 – Dismissile

+0

我也不同意,這是一個非常不穩定的解決方案 - 應用程序通過異常的控制流程在我的壞代碼屬性列表中非常高。 – keithwarren7

+0

@ keithwarren7 - 這不是控制流。您沒有使用例外來決定更新記錄或插入記錄。那會很糟糕。這是用戶插入重複記錄的情況。你唯一的選擇是首先查詢數據庫,但你說你不想這樣做。 –