8

我看過的Repository Patterns的例子都沒有包含任何類型的錯誤處理。 這是爲什麼?舉例來說,我有這個:試試看Catch

public virtual TItem Insert<TItem>(TItem item) where TItem:class,new() 
    { 
     dbContext.Set<TItem>().Add(item); 
     try 
     { 
      dbContext.SaveChanges(); 
     } 
     catch (DbUpdateException) 
     { 

      return null; 
     } 

     return item; 

    } 

一個我們違反約束的實例。我捕捉到DbUpdateException ...如果不在存儲庫本身中,這個錯誤處理將在何處生效?

回答

3

大部分情況下,存儲庫不需要擔心處理異常。正在使用這些存儲庫的類應該處理該類。在你的例子中,爲什麼要在發生插入錯誤時返回null?這不是比拋出異常更清楚嗎?

例如,假設我們想通過存儲庫插入一條記錄,然後打印出新的ID。假設插入將因任何原因失敗。

var myNewItem = myRepository.Insert(myItem); 
Console.WriteLine("MyItem added with ID: {0}", myNewItem.ID); 

繼在你的問題的模式,你會得到一個NullReference例外,在第二行,如果Insert失敗。這有點奇怪。在第一行看到DbUpdateException更清楚。最好能夠依靠Insert總是返回一個有效的實例或拋出一個異常。

+0

我沒有問題拋出DbUpdate異常,它比我同意的NullRefrence更乾淨。回到sotred程序那天,我們會使用,如果不存在。很顯然,我對數據模型持有不同的看法。那麼如何使一個實體足夠聰明,在插入之前檢查記錄? – 2011-04-06 04:08:13

+0

一種方法是在插入之前使用某種驗證器來檢查約束條件,以便提供友好的錯誤消息。或者你可以捕獲數據庫在任何使用版本庫時拋出的約束異常。無論哪種方式,我不認爲這是存儲庫的工作,以確定是否可以插入記錄。 – rsbarro 2011-04-06 04:24:40

+0

我同意,當我完成存儲庫代碼並實際爲消費者連接一些DI時,我將穿越該橋。 – 2011-04-06 04:28:06

9

在設計合理的系統中,約束永遠不能違反。例如,讓您的實體變得更加智能:不要使用盲目的自動執行的設置器。

存儲庫不是做數據驗證的地方。適當的地方是:

  • 如果您只是檢查「契約」約束,例如「數量應該是一個非負整數」或「不要給我一個空客戶」,將邏輯放在實體本身(適當的時候可以是setter或構造函數或變異方法)。
  • 如果您正在檢查業務邏輯,請將其放入抽象出該邏輯的專用對象(如果您願意,則使用DDD規範)。

唯一的一次,這些異常應該拿出是當你運行你單元集成測試,你會得到一個失敗,這就會發現,無論是你的數據庫的約束不匹配與你的實體,或您的實體正確實施。所以你絕對不應該catch他們。