2012-03-22 91 views
4

你會怎麼設計這個方案來處理實體框架和存儲庫模式DB例外(使用實體框架4.1,代碼第一次和存儲庫模式): 的Visual Studio解決方案包含以下項目

Solution 
|-Web Application Project 
|-DAL Project 
|-Model Project 

所以在模型項目中有各種類。假設我們在那裏叫用戶,定義如下(精簡)類:

public class User{ 

    [Key] 
    public int UserId { get; set; } 

    .... 

    //this property has a unique constraint created in a custom DB Initializer class 
    public string email { get; set; } 

    .... 
} 

在DAL項目所在的庫方法(插入,更新等),並初始化類:

public class MyDatabaseInitializer : IDatabaseInitializer<MyDatabase> 
{ 
    public void InitializeDatabase(MyDatabase context) 
    { 
     try 
     { 
      if (!context.Database.Exists()) 
      { 
       context.Database.Create(); 
       context.Database.ExecuteSqlCommand(
        "ALTER TABLE Users ADD CONSTRAINT uc_Email UNIQUE(Email)"); 
      } 
     } 
     catch (Exception ex) 
     { 
      throw ex.InnerException; 
     } 
    } 
} 

提交我的工作類股的方法是這樣的:

public string Commit() 
{ 
    string errorMessage = string.Empty; 

    try 
    { 
     Database.Commit(); 
    } 
    catch (DbUpdateException updExc) 
    {         
     errorMessage = updExc.InnerException.Message;    
    }      

    return errorMessage; 
} 

正如你看到的,我處理DbUpdateExceptionCommit()方法工作單元班;這意味着每個類可能會導致更新錯誤,這將在這裏處理。

假設一個插入用戶記錄如下數據:

(UserId,....,Email,...) 
1, ... , [email protected] , ... 
2, ... , [email protected] , ... 

,很明顯,這將導致發生DbUpdateException。當然,這可以被捕獲並傳播到它應該出現的地方。我有一種感覺,這樣的設計是完全錯誤的:

  1. 驗證應單獨出現每個屬性:不應該這是真的也爲現場的值的唯一性?這是否意味着我必須將DAL和MODEL合併到一個項目中?

  2. 我該如何處理由表A中的fieldA,表B中的fieldB,表C中的fieldC違反唯一性引起的錯誤?使用通用錯誤消息「值已存在」或「唯一性違規」不是很具描述性!

  3. 我應該插入另一個項目 - 業務層來照顧這種錯誤處理嗎?

  4. 我應該在(ASP.NET MVC)操作/控制器中執行更新嗎?

  5. 如何在多語言應用程序中處理正確的錯誤消息?

回答

2

我面臨同樣的情況,此刻我正在處理控制器中的異常。

考慮下面的實體:

public class Part 
{ 
    public int Id { get; set; } 
    public string Number { get; set; } 
} 

我唯一性約束在數據庫中建立在「數字」字段,因此,如果輸入了重複的值是一個將引發異常。這是怎麼了處理異常:

[HttpPost] 
public ActionResult Create(Part part) 
{ 
    if (ModelState.IsValid) 
    { 
     try 
     { 
      db.Parts.Add(part); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     catch (DbUpdateException e) 
     { 
      SqlException s = e.InnerException.InnerException as SqlException; 
      if (s != null && s.Number == 2627) 
      { 
       ModelState.AddModelError(string.Empty, 
        string.Format("Part number '{0}' already exists.", part.Number)); 
      } 
      else 
      { 
       ModelState.AddModelError(string.Empty, 
        "An error occured - please contact your system administrator."); 
      } 
     } 
    } 
    return View(part); 
} 

所有這樣做是回到同一個視圖,並顯示驗證錯誤給用戶這樣的:

enter image description here

我不知道這是多麼'適當',但我現在不能想到一個更好的方法來處理這個問題(EG,即使我在我的DbContext派生類中發現了這個問題,並拋出了一個更具體的異常,我仍然需要在控制器中按順序處理它在運行時對它做任何事情)。

我也不確定是否需要檢查內部異常。我修改了this的帖子,該帖子主要檢查內部異常中的SqlException,並在向用戶報告之前檢查錯誤號(在本例中爲2627,這是唯一鍵約束)。如果SQL錯誤號是其他內容,則會顯示一般性錯誤消息。

更新:

我現在處理的域名服務類,這是example shown here,讓我來處理控制器外部異常的衍生物例外。