2009-10-21 26 views
2

這是一個壞主意嗎?有沒有更好的方法來達到同樣的效果?這樣使用嵌套的Try..Catch塊不好嗎?

// assume that "name" is a string passed as a parameter to this code block 
try 
{ 
    MainsDataContext dx = new MainsDataContext(); 
    try 
    { 
     Main m = dx.Main.Single(s => s.Name == name); 
     return m.ID; 
    } 
    catch (InvalidOperationException) 
    { 
     Guid g = Guid.NewGuid(); 

     Main s = new Main 
     { 
      Name = name, 
      ID = g 
     }; 

     dx.Mains.InsertOnSubmit(s); 
     dx.SubmitChanges(); 

     return g; 
    } 
} 
catch (Exception ex) 
{ 
    // handle this 
} 

這裏的目的是讓如果它存在的記錄的ID,否則創建一個記錄並返回它的ID。

回答

6

您應該使用SingleOrDefault,如果記錄不存在,它將返回爲空的類的默認值。

MainsDataContext dx = null;  
try 
    { 
     dx = new MainsDataContext(); 

     Main m = dx.Main.SingleOrDefault(s => s.Name == name); 

     if (m == null) 
     { 
      Guid g = Guid.NewGuid(); 

      m = new Main 
      { 
       Name = name, 
       ID = g 
      }; 

     dx.Mains.InsertOnSubmit(m); 
     dx.SubmitChanges(); 

     } 

     return m.ID; 
    } 
    catch (Exception ex) 
    { 
     // handle this 
    } 
    finally 
    { 
     if(dx != null) 
      dx.Dispose(); 
    } 

它是使用關鍵字使用一個好主意,使用一個DataContext

using (MainsDataContext dx = new MainsDataContext()) 
{ 
     Main m = dx.Main.SingleOrDefault(s => s.Name == name); 

     if (m == null) 
     { 
      Guid g = Guid.NewGuid(); 

      m = new Main 
      { 
       Name = name, 
       ID = g 
      }; 

     dx.Mains.InsertOnSubmit(m); 
     dx.SubmitChanges(); 

     } 

     return m.ID; 
} 
+0

什麼是dx.Dispose()for?不應該由GC自動處理?我應該使用LinqToSql將它放入所有try..catches的'finally'部分嗎? – Nate 2009-10-21 16:58:31

+0

@Nate,使用DataContext時,最好在using語句**中使用它(使用(DataContext dx = new .......)**),這將確保連接儘快關閉可能的並且對象被處置。由於我們在這裏使用try-catch,我們需要確保無論我們如何處理我們的連接。例外與否。 – 2009-10-21 17:00:03

+0

這只是確保連接快速關閉? GC會最終自行關閉它嗎?現在你指出它使得senes,我只是不明白是必要的,或者只是一個好主意? – Nate 2009-10-21 17:04:52

6
Main m = dx.Main.SingleOrDefault(s => s.Name == name); 

if (m == default(Main)) 
{ 
    // it does not exist 
} 
else 
{ 
    // it does exist 
} 

它不是從問題顯而易見時,如果類型 Main是一個類或一個結構 (編輯:我剛剛意識到,實際上它必須是一類),因此我使用default()而不是僅僅比較null

+0

這回答了具體情況;當SingleOrDefault()不可用時,使用嵌套try..catch塊的更一般的想法是什麼?這是一個壞主意嗎? – Nate 2009-10-21 16:57:17

+1

@Nate Bross:例外情況適用於特殊情況。投擲和捕捉異常是一項非常昂貴的操作,並且不會讓您的代碼非常易讀。儘量避免它們用於正常的控制流程(比如這個),並且只有在程序中出現異常情況時才使用它們。 – 2009-10-21 17:00:56

+0

@DrJokepu:在使用Ling to SQL插入/更新/刪除時應該使用異常嗎?還是應該在其他地方處理? – keyboardP 2009-10-21 17:03:41

0

不,但您可能想要將內部塊反射爲外部方法。

+3

重構,而不是反射器:P – 2009-10-21 16:58:38

1

我的問題是你打算在這裏放什麼代碼:

// handle this 

隨着第一個catch塊,你知道單身()拋出一個InvalidOperationException,因爲序列包含多個元素或爲空。

在第二個,你可以得到各種錯誤。空引用,數據訪問等。你將如何處理這些?

只抓住你知道如何處理,並儘可能在異常類型中具體。

+0

Catch(Exception ex)是一個安全網絡,它是一個縮寫代碼片段,它基本上做了一些日誌記錄,然後拋出;在表示層處理的異常。 – Nate 2009-10-21 17:02:33

+0

@Nate - 這是完全可以接受的。記錄+重新拋出是捕捉基類異常是一個好主意的少數情況之一。 – TrueWill 2009-10-21 17:55:13

0

無論如何,我認爲嵌套Try Catch塊是好的,就像兄弟Catch塊每個捕捉不同的問題。對錯誤進行具體分析是很好的。全部應該只是生產的安全網。