2013-04-03 36 views
0

我有以下我的應用程序: 行動奧姆實體(從Telerik的開放式接入),當我需要保存一個實例 庫(行動) AppService服務(存放在倉庫的一個實例)驗證功能應該直接訪問存儲庫嗎?

,我送實例到AppService。 AppService然後調用驗證器來驗證要保存的實例。驗證是基於http://codeinsanity.com/archive/2008/12/02/a-framework-for-validation-and-business-rules.aspx (上https://github.com/riteshrao/ncommon完整的代碼)

所以基本上我保存功能在AppService服務看起來像這樣

Public Sub AddAction(ByVal Item As Data.Model.Action) 
     Contract.Requires(Of ArgumentNullException)(Item IsNot Nothing, "Item is nothing.") 

     Dim validateResult As Rules.ValidationResult = _ActionValidator.Validate(Item) 
     If Not validateResult.IsValid Then 
      Throw New Validation.ValidationException(validateResult) 
     End If 

     Try 
      _ActionRepository.Add(Item) 
      _unitOfWork.SaveChanges() 
     Catch ex As Exception 
      _unitOfWork.ClearChanges() 
      Throw New DataServiceException(ex.Message, ex) 
     End Try 

    End Sub 

檢查行動項目的示例代碼的偉大工程的性質。我的問題開始時,我需要確保相同的行動沒有添加兩次到數據庫爲同一個客戶(即身份證是差異,名稱是相同的,客戶是相同的)

因爲我看到它我有幾個選項: 選項1:使用類似

function(validatedItem) item.Customer.Actions.Any(function(item) item.id<>validatedItem.id andalso item.name=validatedItem.name)) 

基本上我從行動去被保存返還給客戶,然後回到他的一切行動檢查是否有重複的動作,並檢查是否有任何行動存在不同的ID和相同的名稱

down si des是:

a。爲此,在訪問該項目的客戶屬性時,將從DB中讀取整個客戶對象,在這種情況下,這是冗餘的 b。任何函數都在客戶端上評估爲item.Customer.Actions返回IList(Of Action)

選項2:讓驗證類可以訪問操作存儲庫。那麼我可以簡單地這樣做

'assume I already have validatedItem 
repository.Any(function(item) item.id<>validatedItem.id and item.customerid=validatedItem.customerid and item.name=validatedItem.name) 

這將導致一個EXISTS查詢被髮送到數據庫但下行(?)是驗證框架不應該直接訪問存儲庫(據我所看到的在極少數例子中,我可以發現使用驗證和ORM)

選項3:讓驗證類有權訪問AppService並使用AppService檢查是否存在重複。問題: a。我創建了一個循環引用(AppService-> Validation Class-> AppService) b。我需要在AppService中創建許多無用功能,用於根據僅與驗證相關的條件加載項目

任何想法這裏最好的課程是什麼?

回答

2

最簡單的辦法就是不要從域中檢查數據庫中的重複項。

當實體的集合是你的一部分時,那麼這是一個非問題,因爲你不允許將重複添加到集合中。由於聚合是作爲一個整體存儲的,所以你永遠不會遇到問題。

對於您不希望重複(例如電子郵件地址)且實體的集合沒有由集合表示(例如系統中的Users)的場景,您可以讓數據庫強制執行唯一性。只需拿起例外並回報。在許多情況下,您的驗證將無法完成唯一性,因爲它沒有/實現數據庫系統所需的鎖。

所以我只是簡單地將直接留給數據庫。