2010-05-24 4 views
3

Je trouve très ennuyeux d'écrire une instruction using sur chacune de mes requêtes (qui nécessitent sa propre commande ou écrivent paramètres.clear()) qui nécessitent parfois de déclarer des variables en dehors du bloc using. C'est si incroyablement agaçant et semble beaucoup plus sale par rapport à la version sans disposer de l'objet.Dois-je disposer de MySqlCommand?

Dois-je m'en débarrasser? que se passe-t-il si je ne le fais Je connais sa bonne pratique de disposer d'un objet quand il a cette interface.

Répondre

4

D'un rapide coup d'œil dans le réflecteur, il semble appeler CloseStatement() sur son PreparableStatement, puis appeler Dispose() sur ses superclasses, y compris System.ComponentModel.Component. NativeDriver.CloseStatement32 (id), qui écrit une commande dans le flux de connexion.

Ce n'est pas le genre de chose que je voudrais éviter. Pourquoi le risquer?

C'est l'une de ces périodes où vous devez ajuster votre propre pensée. Vous pourriez penser que using a l'air «sale», mais - comme de l'huile fraîche luisante sur un système d'engrenages - c'est en fait un signe de propreté. Vous pourriez être capable d'écrire une abstraction pour le cacher, mais vous ne devriez pas vous en débarrasser.

+1

+1 J'aime l'analogie. –

2

Si vous ciblez ASP.NET, vous pouvez configurer votre méthode Connect() (si vous en avez une) pour configurer également un finaliseur à exécuter lorsque la page est déchargée. Cette astuce est également utile si vous rencontrez des problèmes avec les pools de connexions qui sont épuisés.

J'ai également inclus une méthode Exec pour simplifier l'écriture de commandes SQL avec des paramètres de typesafe - comme dans la méthode Test.

using System; 
using System.Web; 
using System.Data.SqlClient; 
using Conf = System.Configuration.ConfigurationManager; 
using System.Data; 

public static class Sql { 
    public static SqlConnection Connect() { 
     // create & open connection 
     SqlConnection result = new SqlConnection(Conf.ConnectionStrings["connectionString"].ConnectionString); 
     result.Open(); 

     // add delegate to trigger when page has finished, to close the connection if it still exists 
     System.Web.UI.Page page = HttpContext.Current.Handler as System.Web.UI.Page; 
     if (page != null) { 
      page.Unload += (EventHandler)delegate(object s, EventArgs e) { 
       try { 
        result.Close(); 
       } catch (Exception) { 
       } finally { 
        result = null; 
       } 
      }; 
     } 

     // return connection 
     return result; 
    } 

    public static SqlDataReader Exec(string name, params object[] parameters) { 
     using (SqlCommand cmd = Connect().CreateCommand()) { 
      cmd.CommandTimeout = int.Parse(Conf.AppSettings["commandTimeoutSec"]); 
      cmd.CommandType = CommandType.Text; 
      cmd.CommandText = name; 
      for (int x = 0; x + 1 < parameters.Length; x += 2) { 
       SqlParameter p = cmd.Parameters.AddWithValue((string)parameters[x], parameters[x + 1]); 
       if (parameters[x + 1] is string) { 
        p.DbType = DbType.AnsiString; 
       } 
      } 
      return cmd.ExecuteReader(CommandBehavior.CloseConnection); 
     } 
    } 

    public static void Test() { 
     using (SqlDataReader reader = Exec(
      "SELECT * FROM member WHERE [email protected] AND age=YEAR(GETDATE())[email protected]", 
      "@firstname", "tom", 
      "@yearborn", 1978)) { 
      while (reader.Read()) { 
       // read 
      } 
     } 
    } 
}