2010-04-29 24 views
0

Je me demandais s'il y aurait une approche confiante à utiliser dans la section catch du bloc try-catch lors du développement d'opérations CRUD (spécialement lorsque vous utilisez une base de données comme source de données) dans .Net?.Net: Quelle est votre approche confiante dans la section «Catch» du bloc try-catch, Lors du développement des opérations CRUD?

Eh bien, quelle est votre opinion sur les lignes ci-dessous?

public int Insert(string name, Int32 employeeID, string createDate) 
    { 
     SqlConnection connection = new SqlConnection(); 
     connection.ConnectionString = this._ConnectionString; 
     try 
     { 
      SqlCommand command = connection.CreateCommand(); 
      command.CommandType = CommandType.StoredProcedure; 
      command.CommandText = "UnitInsert"; 
      if (connection.State != ConnectionState.Open) 
       connection.Open(); 
      SqlCommandBuilder.DeriveParameters(command); 
      command.Parameters["@Name"].Value = name; 
      command.Parameters["@EmployeeID"].Value = employeeID; 
      command.Parameters["@CreateDate"].Value = createDate; 
      int i = command.ExecuteNonQuery(); 
      command.Dispose(); 
      return i; 
     } 
     catch 
     { 
      **// how do you "catch" any possible error here?** 
      return 0; 
      // 
     } 
     finally 
     { 
      connection.Close(); 
      connection.Dispose(); 
      connection = null; 
     } 
    } 
+0

Totalement sur une tangente, mais vous devriez essayer d'utiliser les instructions 'using', plutôt que' try'/'finally' et d'appeler vous-même' Dispose'. http://msdn.microsoft.com/en-us/library/yh598w02(VS.80).aspx –

+0

Pourquoi vérifiez-vous si l'état de la connexion est ouvert? Il ne sera pas ouvert, donc appelez 'Open' sans le précédent si. –

+0

@Matthew: BTW, qu'est-ce que cela signifie: totalement sur une tangente? – odiseh

Répondre

3

J'utiliserais une instruction using pour les démarreurs.

Je ne retournerais pas 0 comme un échec. Vous pouvez mettre à jour avec succès aucun enregistrement et donc 0 serait un code de réponse de succès valide. L'utilisation de -1 indique clairement que quelque chose s'est mal passé. Personnellement, je préfère lancer une exception au cas où quelque chose d'inattendu se produirait.

try 
    { 
     using (SqlConnection connection = new SqlConnection()) 
     { 

      connection.Open();   

      using(SqlCommand command = connection.CreateCommand()) 
      { 
        command.CommandType = CommandType.StoredProcedure; 
        command.CommandText = "UnitInsert"; 

        SqlCommandBuilder.DeriveParameters(command); 
        command.Parameters["@Name"].Value = name; 
        command.Parameters["@EmployeeID"].Value = employeeID; 
        command.Parameters["@CreateDate"].Value = createDate; 

        return command.ExecuteNonQuery(); 
       } 

     } 
     } 
     catch(Exception ex) 
     { 
      LogException(ex); 
      return either -1 or re throw exception. 
     } 
+1

+1. En outre, je voudrais lancer une exception personnalisée, comme 'throw new MyCustomException (" Impossible de créer un employé ", ex);' –

+0

@klausbyskov c'est aussi un bon point. – kemiller2002

+1

@odiseh vous pourriez avoir un bloc catch où vous n'attrapez pas l'exception, mais alors vous n'avez aucune idée de ce qui s'est mal passé. Je fais toujours une règle que vous devez faire quelque chose avec l'exception. Même si c'est attraper une exception particulière et l'ignorer. – kemiller2002

2

À mon avis, cela est tout à fait le bon endroit pour attraper quelque chose que vous ne pouvez pas gérer là-bas et puis. Laisser l'exception exploser et demander à l'application appelante de mettre en œuvre sa propre gestion des erreurs. Si vous attrapez et avalez une exception ici, votre débogage pour les applications installées va être cauchemardesque.

Seulement jamais attraper ce que vous pouvez manipuler et jeter tout le reste ...

0

Je ferais un

catch(Exception ex){ 
    // log exception here and set return value 
} 
0

J'aime formaliser l'API de mon DAL en sous-traitant toutes les exceptions à quelques sélectionner et imbriquant l'exception réelle en tant que InnerException. Par exemple, toutes les exceptions de base de données qui ne sont pas la faute des appelants produiraient un type d'exception, toutes les exceptions de base de données qui sont la faute des appelants (par exemple, aucune ligne sélectionnée, PK non valide, données non valides) exception (ou peut-être même avoir une distinction plus fine entre les types d'exception), et un dernier type d'exception pour les choses qui ne sont pas liées à la base de données (contrôles de santé, NullRef, etc), sauf pour les exceptions OutOfMemoryException).

De cette façon, il est facile d'attraper les exceptions que je lance dans mon DAL, et tous les détails sanglants spécifiques sont toujours disponibles en InnerException.