从c#处理到MySql的Connections的最佳方法是什么?

时间:2010-06-04 06:26:03

标签: c# mysql

我正在开发一个连接到MySql服务器的c#应用程序。大约有20个函数将连接到数据库。该应用程序将部署在200台以上的机器上。我使用以下代码连接到我的数据库,这对所有功能都是相同的。问题是,我可以在200多台机器上部署时,某些连接没有关闭并且仍然存在。

连接字符串:

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

在应用程序[Global.cs]中全局声明连接字符串:

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

查询数据库的功能:

  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;
        }

4 个答案:

答案 0 :(得分:6)

您应该使用一次性使用工作单元方法。 MySqlConnection类型是一次性的,因此应使用块干净地包装:

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

这样做,是否确保在连接对象上调用Dispose(),从而关闭连接。这非常重要。

我也注意到你正在为你的连接字符串使用appSettings,配置文件中实际上有一个专用的connectionStrings元素:

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

您可以使用它来创建连接实例:

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

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

最后一点,您应该尝试使用参数化查询,以防止SQL注入攻击:

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

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

希望有所帮助!

答案 1 :(得分:3)

The root cause of the problem is the global single instance of your connection object.我不建议在整个应用程序中保留单个连接实例。在unit-of-work context/scope中的任何位置创建,打开,关闭,处置连接。还尝试将连接字符串移动到app.config中的部分。

答案 2 :(得分:3)

我建议您将连接处理留给ADO.NET connection pool,不要使用任何静态对象。参数化查询也不容易受到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())
        {

        }
    }
}

答案 3 :(得分: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);
    }
}