2010-07-31 7 views
3

Quel modèle est meilleur pour SqlConnection objet? Quel est le meilleur en performance? Offrez-vous un autre motif?Quel modèle est meilleur pour l'objet SqlConnection?

class DataAccess1 : IDisposable 
{ 
    private SqlConnection connection; 

    public DataAccess1(string connectionString) 
    { 
     connection = new SqlConnection(connectionString); 
    } 

    public void Execute(string query) 
    { 
     using (SqlCommand command = connection.CreateCommand()) 
     { 
      command.CommandText = query; 
      command.CommandType = CommandType.Text; 
      // ... 

      command.Connection.Open(); 
      command.ExecuteNonQuery(); 
      command.Connection.Close(); 
     } 
    } 

    public void Dispose() 
    { 
     connection.Dispose(); 
    } 
} 

VS

class DataAccess2 : IDisposable 
{ 
    private string connectionString; 

    public DataAccess2(string connectionString) 
    { 
     this.connectionString = connectionString; 
    } 

    public void Execute(string query) 
    { 
     using (SqlConnection connection = new SqlConnection(connectionString)) 
     { 
      SqlCommand command = connection.CreateCommand(); 
      command.CommandText = query; 
      command.CommandType = CommandType.Text; 
      // ... 

      command.Connection.Open(); 
      command.ExecuteNonQuery(); 
      command.Connection.Close(); 
     } 
    } 

    public void Dispose() 
    {    
    } 
} 

Répondre

1

Suggestion allant de DataAccess2. C'est une préférence personnelle cependant. Certains pourraient même suggérer que votre classe soit static. Il serait difficile de dire que l'un est plus performant que l'autre. Vous êtes sur le chemin de IDisposable, ce qui est génial.

Je serais heureux de lire et de maintenir les deux styles montrés ci-dessus dans votre question. Envisagez d'avoir votre DAL capable de lire la chaîne de connexion à partir d'un .config, plutôt que de permettre exclusivement la transmission de la valeur dans le constructeur.

public DataAccess2(string connStr) 
{ 
    this.connectionString = connStr; 
} 
public DataAccess2() 
{ 
    this.connectionString = 
      ConfigurationManager.ConnectionStrings["foo"].ConnectionString; 
} 

Tenir compte emballer vos SqlCommand dans un using aussi bien.

using (var conn = new SqlConnection(connectionString)) 
{ 
    using(var cmd = conn.CreateCommand()) 
    { 

    } 
} 
+2

Je conseillerais * contre * ayant la classe lire la chaîne de connexion. Laissez l'application lire les informations de configuration et les transmettre au consommateur; il n'y a aucune raison de limiter la portabilité de la classe. –

+0

@Adam: Je suis d'accord avec vous sur la * limitation * de la portabilité.Je vais modifier pour inclure un ctor qui permettrait à l'appelant de fournir la valeur. –

3

Il n'y a pas de véritable moyen de répondre à cette question. La réponse courte et canonique est que la connexion devrait rester en vie pendant toute la durée de votre unité de travail. Parce que nous n'avons aucun moyen de savoir comment est utilisé DataAccess (existe-t-il pour la durée de vie de votre application, ou l'instanciez-vous et l'éliminez-vous quand vous faites quelque chose?), Il est impossible de donner une réponse concrète. Cela étant dit, je recommanderais le premier modèle, mais instanciez et jetez votre objet DataAccess au besoin; ne le gardez pas plus longtemps que nécessaire.

0

Je pense que cela dépend de la façon dont votre objet DataAccess est destiné à être utilisé, s'il est utilisé dans une clause 'using', la connexion est garantie après avoir terminé. Mais en général, je préfère le second modèle car la connexion sql est créée et éliminée dans la méthode Execute, donc elle est moins susceptible d'être laissée ouverte lorsque vous oubliez de disposer de votre objet DataAccess. Considérant que la connexion SQL peut être une ressource rare, je pense que tout devrait être fait pour s'assurer qu'ils ne sont pas gaspillés.

0

La première entraînera des erreurs si vous effectuez des appels simultanés. La seconde veillera à utiliser une connexion propre pour chaque commande, ce qui augmentera les connexions. Je suis d'accord avec les déclarations ci-dessus que cela dépend du scénario d'utilisation, pour résoudre le problème lié à la première J'ai un wrapper qui a besoin d'utiliser un tel modèle, donc j'ai mis une valeur de champ booléen pour montrer qu'un commande est en cours d'exécution sur la connexion déjà "queue" la commande suivante pour l'exécution.

Il y aura bien sûr des situations où vous préférerez peut-être utiliser plusieurs connexions ...

Questions connexes