2010-06-04 5 views
4

Je travaille sur une application C# qui se connecte au serveur MySql. Il y a environ 20 fonctions qui se connecteront à la base de données. Cette application sera déployée dans 200 sur des machines. J'utilise le code ci-dessous pour me connecter à ma base de données qui est identique pour toutes les fonctions. Le problème est, je peux certaines connexions ne sont pas fermées et encore en vie lorsqu'ils sont déployés dans 200 sur des machines.Quelle est la meilleure façon de gérer les connexions à MySql de C#

chaîne de connexion:

<add key="Con_Admin" value="server=test-dbserver; database=test_admindb; uid=admin; password=1Password; Use Procedure Bodies=false;" /> 

Déclaration de la chaîne de connexion globalement dans la demande [Global.cs]:

public static MySqlConnection myConn_Instructor = new MySqlConnection(ConfigurationSettings.AppSettings["Con_Admin"]); 

fonction de base de données recherche:

public static DataSet CheckLogin_Instructor(string UserName, string Password) 
     { 
      DataSet dsValue = new DataSet(); 
      //MySqlConnection myConn = new MySqlConnection(ConfigurationSettings.AppSettings["Con_Admin"]); 
      try 
      { 
       string Query = "SELECT accounts.str_nric AS Nric, accounts.str_password AS `Password`," + 
         " FROM accounts " + 
         " WHERE accounts.str_nric = '" + UserName + "' AND accounts.str_password = '" + Password + "\'"; 

       MySqlCommand cmd = new MySqlCommand(Query, Global.myConn_Instructor); 
       MySqlDataAdapter da = new MySqlDataAdapter(); 
       if (Global.myConn_Instructor.State == ConnectionState.Closed) 
       { 
        Global.myConn_Instructor.Open(); 
       } 

       cmd.ExecuteScalar(); 
       da.SelectCommand = cmd; 
       da.Fill(dsValue); 
       Global.myConn_Instructor.Close(); 
      } 
      catch (Exception ex) 
      { 
       Global.myConn_Instructor.Close(); 
       ExceptionHandler.writeToLogFile(System.Environment.NewLine + "Target : " + ex.TargetSite.ToString() + System.Environment.NewLine + "Message : " + ex.Message.ToString() + System.Environment.NewLine + "Stack : " + ex.StackTrace.ToString()); 
      } 

      return dsValue; 
     } 

Répondre

6

Vous devez utiliser une unité de travail en utilisant l'approche à usage unique. Le type de MySqlConnection est à usage unique, devrait donc être enveloppé proprement dans des blocs en utilisant:

using (MySqlConnection connection = CreateConnection("Con_Admin")) { 
    // Do work here. 
} 

Ce que cela fait, est-il garantit que Dispose() est appelée sur l'objet de connexion, qui ferme la connexion. C'est incroyablement important.

J'ai aussi remarqué que vous utilisez appsettings pour vos chaînes de connexion, il est en fait un élément connectionStrings dédié dans un fichier de configuration:

<connectionStrings> 
    <add name="Con_Admin" connectionString="..." providerName="MySql.Data" /> 
</connectionStrings> 

que vous pouvez utiliser pour créer des instances de connexions:

public MySqlConnection CreateConnection(string name) 
{ 
    if (string.IsNullOrEmpty(name)) 
    throw new ArgumentException("Connection name must be provided", "name"); 

    string connection = ConfigurationManager.AppSettings[name].ConnectionString; 
    return new MySqlConnection(connection); 
} 

Le dernier point d'intérêt, vous devriez essayer d'utiliser des requêtes paramétrées, qui protègent contre les attaques par injection sQL:

string query = "SELECT * FROM SomeTable Where SomeField = @field"; 

using (MySqlCommand command = new MySqlCommand(query)) 
{ 
    command.Parameters.AddWithValue("@field", "someFieldValue"); 
} 

Espérons que ça aide!

+0

Merci pour votre publication. Quelque chose à faire avec la chaîne de connexion aussi? Comme la taille de la piscine !! – Anuya

+0

Les connexions sont regroupées en fonction de la chaîne de connexion proprement dite, donc avoir une chaîne de connexion singulière devrait être bien (c'est une autre raison d'utiliser l'élément de configuration connectionStrings). En outre, y a-t-il une exigence concernant l'utilisation de DataSets, pouvez-vous faire de même avec DataReaders, qui sont des lecteurs rapides, uniquement en avant? –

3

The root cause of the problem is the global single instance of your connection object. I don Ne recommande pas de garder une seule instance de connexion à travers l'application. Créer, Ouvrir, Fermer, Débarrassez-vous de la Connexion partout où cela est nécessaire dans le unit-of-work context/scope. Essayez également de déplacer votre chaîne de connexion à section dans votre app.config.

3

Je vous recommande de laisser le traitement de la connexion au ADO.NET connection pool et n'utilisez aucun objet statique. Aussi les requêtes paramétrées ne sont pas vulnérables aux attaques par injection SQL:

using (var conn = new MySqlConnection(ConfigurationSettings.AppSettings["Con_Admin"])) 
using (var cmd = conn.CreateCommand()) 
{ 
    conn.Open(); 
    cmd.CommandText = @"SELECT accounts.str_nric AS Nric, accounts.str_password AS `Password` 
         FROM accounts WHERE accounts.str_nric = @Username 
         AND accounts.str_password = @Password"; 
    cmd.Parameters.AddWithValue("@Username", Username); 
    cmd.Parameters.AddWithValue("@Password", Password); 
    using (var reader = cmd.ExecuteReader()) 
    { 
     while (reader.Read()) 
     { 

     } 
    } 
} 
1
private void LoginPage_Load(object sender, EventArgs e) 
{ 
    try 
    { 
     string connectionString = String.Format("server=192.168.1.12;port=3306;database=taskmanagement;UID=root;password="); 

     using (MySqlConnection connection = new MySqlConnection(connectionString)) 
     { 
      connection.Open(); 
      Console.WriteLine("connect"); 
      connection.Close(); 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 
} 
+1

erreur dans la connexion. plz le trouver et m'aider .. –

Questions connexes