2012-04-17 72 views
4

在這個特定的應用程序中,沒有單獨的數據層,數據訪問代碼位於實體本身中。例如,考慮一個客戶實體,然後在Customer.cs文件,其中的成員和屬性的定義,則必須方法來加載客戶對象,如下當數據庫的數據不好時,應該拋出異常嗎?

public bool TryLoad(int customerID, out Customer customer) 
{ 
    bool success = false 
    try 
    { 
     //code which calls the db and fills a SqlDataReader 
     ReadDataFromSqlDataReader(reader); 
     success = true; 
    } 
    catch(Exception ex) 
    { 
     LogError(); 
     success = false; 
    } 
    return success; 
} 

現在,在ReadDataFromSqlDataReader(讀取器),的TryParse用於將數據從閱讀器加載到對象中。例如

public void ReadDataFromSqlDataReader(reader) 
{ 
    int.TryParse(reader["CustomerID"].ToString(), out this.CustomerID); 
    PhoneNumber.TryParse(reader["PhoneNumber"].ToString(), out this.PhoneNumber); 
    ... similar TryParse code for all the other fields.. 
} 

正在使用TryParse來讀取讀者的所有屬性一個很好的做法?一位開發者告訴我,它以TryParse的方式完成比int.Parse更好的性能。但是當你從數據庫中讀取的值不符合你的代碼所期望的值時,你是否想要拋出異常?我的意思是在這種情況下,如果數據庫中有錯誤的電話號碼,那麼可能對象不應該被初始化,而是用一個空的電話號碼加載一個對象?

+0

聽起來特殊 – Jodrell 2012-04-17 14:39:42

+0

如果您想要處理不良數據,'TryParse'只有更好的'Parse'性能。 – user7116 2012-04-17 14:41:03

+0

我無法想象表演有什麼不同。它吞下異常,因此實際上包含了您將在外部使用.Parse寫入的相同代碼。 – 2012-04-17 14:41:51

回答

4

是的,遵循快速原型原則,您希望在值返回時無法轉換爲預期類型時拋出異常。

如果其中一個操作失敗,並且您繼續如同沒有任何事情發生一樣,那麼您可能會遇到難以捕捉且難以查明的怪異錯誤:當它們應該更新現有行時將對象添加到數據庫,數據神祕消失,狗和貓一起生活......你明白了。另一方面,如果立即拋出異常,您就可以確切地知道問題出在哪裏,並且可以在問題變得更糟之前抓住並解決問題。

TryParse如果因爲沒有必要拋出一個異常(這可能很貴)而失敗時,它的工作速度會比Parse快,但是如果你認爲事情會成功(這個代碼是做不到的使用解析結果),您應該使用Parse獲得相同的性能。

+0

因爲'TryParse'返回布爾值。所以,我可以''ByPass/Continue'根據'布爾'值'提出'邏輯/任何數據庫'請求。我不會讓這種情況發生在這樣的場景中。爲此,我會做日誌等 – Pankaj 2012-04-17 15:26:42

0

當數據插入和/或更新時,您正在做什麼樣的驗證?

只要你在這裏應用某種形式的驗證,我個人不會驗證數據庫中出來的數據,因爲你應該確信你只輸入了有效的數據。

+1

你能100%保證它總是會是好數據嗎?當dba直接打開表格並輸入「stjkerij」作爲電話號碼時會發生什麼? – JonH 2012-04-17 14:43:57

+1

問題在於系統開發時最初沒有驗證。例如,PhoneNumber不是代碼中定義的類型,基本上是一個字符串。幾年後,其中一名開發人員將PhoneNumber定義爲一種類型,現在大多數情況下只要插入數據,它就是有效的數據。但是,這是舊代碼的混亂,我不能100%確定來自數據庫的數據總是有效的。另外,如果我失敗並記錄這些,我實際上可能會清除數據庫中的錯誤數據。 – shashi 2012-04-17 14:52:33

+0

@JonH,無論數據是否好,重要的是你能明智地把它做好,如果不是的話。 – 2012-04-17 14:55:41

0

如果你會處理它,那麼是的你應該拋出異常。但是如果你不關心這個異常,並且如果你要過濾正確的數據並使用它(在這個例子中是非零),你可以跳過。

+0

我衷心不同意。調用這種方法的程序員會假設他們獲得的對象已經完全填充。給他們一個沒有完全填充的對象就是要求麻煩。即使沒有處理代碼,最好讓系統失敗壯觀,並將您的注意力轉移到這樣一個事實上,即您有一個錯誤,而不是讓您的其他代碼使用這些數據,就像沒有任何錯誤一樣。 – StriplingWarrior 2012-04-17 14:49:59

+1

你是對的,但它是一個選項。拋出或不拋出異常取決於你想要做什麼。我說如果你在意你應該拋出一個例外,但這可能並非總是如此。也許他想在用戶界面的「電話號碼」列中顯示一條消息,如「您的電話號碼無效」。 – 2012-04-17 14:56:32

+0

如果我這樣做,它是無效的是一個例外。我會拋出它並將其陷入調用者中,並在調用代碼中處理它。 (或mabe陷阱並引發一個自定義的異常,將代碼中的消息放入代碼中,意味着它不止一件事,意味着你必須做同樣的事情或者破壞DRY,並且會導致糟糕的設計,並且使得任何單元測試都依賴於用戶界面依賴,所以一個選項是的,一個好的我是可疑的 – 2012-04-17 17:30:19

0

As,TryParse返回布爾值。所以,我可以ByPass/ContinueUpcoming Logic/Any Database請求的基礎上Boolean值。我不會讓這種情況發生在這樣的場景中。對於我會做記錄等

解析

  1. 拋出異常。
  2. 使用它,如果你確定值將是有效

的TryParse

  1. 返回一個布爾值,指示是否成功
  2. 它只是試圖/內部趕上爲什麼實施沒有例外,所以它是快速的
  3. 在情況下使用它e值可能是無效的
1

將數據插入到數據庫時將執行有效驗證。這不是一個好的設計,可以在數據庫中輸入錯誤的數據。如果數據庫包含錯誤的電話號碼,則應要求用戶再次輸入電話號碼,如果電話號碼不重要,則可以在電話號碼不正確的情況下將電話號碼初始化爲空。

1

我不會爲此使用TryParse。 如果我的分貝有垃圾,我想要解決。 如果數據在解析方面是不明確的(例如Varchar用int或double作爲字符串) 我想整理我的模式,TryParse作爲類型檢測將是一個快速而簡單的黑客攻擊。

相關問題