2011-11-09 35 views
0

嗨我正在開發一個使用C#和實體框架(LINQ到實體)的winform應用程序。 假設以下escenario:在查詢嘗試c拋出異常的最佳方式#

在某些類的方法,我設置與表單值的對象值

private void agrega_cliente_Click(object sender, EventArgs e) 
{ 
     cliente = new _Cliente(); 

     try 
     { 
      cliente.nombres = nom_cliente.Text; 
      cliente.apellidoP = apellidoP_cliente.Text; 
      cliente.apellidoM = apellidoM_cliente.Text; 
      cliente.fechaNacimiento = fechaNacimientoPicker.Value.Date; 

      if (operaciones.AgregaCliente(cliente, referencias)) 
      { 
       MessageBox.Show("Cliente Agregado"); 
       this.Close(); 
      } 
     } 
     catch(Exception ex) 
     { 
      MessageBox.Show(ex.ToString()); 
     } 
} 

注意,分配新建分配FY和調用到方法「AgregaCliente」是一個嘗試和catch之間,所以如果觸發一個異常,MessageBox會顯示它。

然後在其他類中,我有AgregaCliente方法在數據庫中插入值。

public bool AgregaCliente(_Cliente cliente, ArrayList refes) 
{ 
     try 
     { 
      Cliente cli = new Cliente() 
      { 
       Nombres = cliente.nombres, 
       ApellidoP = cliente.apellidoP, 
       ApellidoM = cliente.apellidoM, 
       FechaNac = cliente.fechaNacimiento 
      }; 
      if (NombreExiste(cli)) 
       context.clientes.AddObject(cli); 
      else 
       throw new System.ArgumentException("El usuario ya existe"); 
      if (refes.Count != 0) 
      { 
       foreach (_Referencia elem in refes) 
        context.referencias_personales.AddObject(AgregaReferencia(elem)); 
      } 
      context.SaveChanges(); 
     } 
     catch (Exception ex) 
     { 
      return false; 
     } 
     return true; 
} 

在此方法中存在要"NombreExiste()"一個呼叫,它檢查該用戶尚未插入,如果用戶存在則拋出異常。

因此,這裏的問題是,如果在"AgregaCliente"方法中拋出異常,我希望通過"agrega_cliente_Click()"方法捕獲此異常,以便用戶知道是什麼引發了問題。我希望你明白我想要做什麼。

感謝

回答

3

簡單地擺脫AgregaCliente()方法中你的try/catch和異常將自動泡起來。

public bool AgregaCliente(_Cliente cliente, ArrayList refes) 
{ 
    Cliente cli = new Cliente() 
    { 
     Nombres = cliente.nombres, 
     ApellidoP = cliente.apellidoP, 
     ApellidoM = cliente.apellidoM, 
     FechaNac = cliente.fechaNacimiento 
    }; 
    if (NombreExiste(cli)) 
     context.clientes.AddObject(cli); 
    else 
     throw new System.ArgumentException("El usuario ya existe"); 
    if (refes.Count != 0) 
    { 
     foreach (_Referencia elem in refes) 
      context.referencias_personales.AddObject(AgregaReferencia(elem)); 
    } 
    context.SaveChanges(); 

    return true; 
} 
+1

+1出色答卷。另外,如果你想對異常進行記錄,你可以刪除'return false'。並用'扔'取而代之 – Robert

+0

另外,由於函數只能返回true或拋出異常,因此可能根本不需要bool返回值,並且可以將其更改爲void。 –

+0

傑出的答案迪倫,謝謝。只是爲了確保,如果拋出其他異常(如數據庫上的重複鍵,格式不正確等),它也會冒泡? –

2

問題是你的AgregaCliente()方法捕獲所有的異常並且簡單地吞下它們。而不是通過以下方式捕獲所有異常:

catch (Exception ex) 
    { 
     return false; 
    } 

您應該只捕獲您可以處理的特定異常並讓其他人通過調用鏈。但是,您應該知道,拋出異常對於程序來說非常「昂貴」。當引發異常時,C#在幕後做了很多工作。更好的解決方案可能是使用返回碼向AgregaCliente()方法的調用者指示狀態。例如:

public enum AgregaClienteStatus 
{ 
    Success = 0; 
    ClientAlreadyExists = 1; 
    Other = ??; // Any other status numbers you want 
} 

public AgregaClienteStatus AgregaCliente(_Cliente cliente, ArrayList refes) 
{ 

      Cliente cli = new Cliente() 
      { 
       Nombres = cliente.nombres, 
       ApellidoP = cliente.apellidoP, 
       ApellidoM = cliente.apellidoM, 
       FechaNac = cliente.fechaNacimiento 
      }; 
      if (NombreExiste(cli)) 
       context.clientes.AddObject(cli); 
      else 
       return AgregaClienteStatus.ClientAlreadyExists 
      if (refes.Count != 0) 
      { 
       foreach (_Referencia elem in refes) 
        context.referencias_personales.AddObject(AgregaReferencia(elem)); 
      } 
      context.SaveChanges(); 


     return AgregaClientStatus.Success; 
} 

當然,如果您不喜歡枚舉,也可以使用常量整數來實現此功能。

然後,您可以使用該返回狀態指示信息給用戶無例外的代價:

var result = AgregaClient(cliente, refes); 
    switch (result) 
    { 
    case AgregaClientStatus.Success: 
     // Perform success logic 
     break; 
    case AgregaClientStatus.ClientAlreadyExists: 
     MessageBox.Show("Client already exists"); 
     break; 
    // OTHER SPECIAL CASES 
    default: 
     break; 
    } 

}

+0

很好的答案,你從AgregaCliente方法刪除嘗試/趕上像上面的答案。如果我需要擴展功能,我會使用你的建議,謝謝 –