I have a generic class that is allowing me to run queries on MySQL database.
The only issue that I am seeing with this class is that it open a connections run a query and close the connection.
Now, I need to be able to
START TRANSACTION;
SELECT ...
INSERT INTO table1...
INSERT INTO table2...
INSERT INTO table3...
- if all the above queries worked with no error
COMMIT;
otherwiseROLLBACK;
Yes, I need a transaction and I need to make sure all queries run 100% or I need to rollback and correct the error prior tarting again.
How can I modify my class to allow me to handle the steps above?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using MySql.Data.MySqlClient;
using System.Windows.Forms;
namespace RM
{
public class dbConnetion
{
//private OdbcConnection conn;
private static readonly string mServer = "localhost";
private static readonly string mDatabase = "my_db_name";
private static readonly string mUid = "my_db_user";
private static readonly string mPassword = "my_user_password";
private static readonly string mPort = "3306";
private string conn_string = String.Format("server={0};user={1};database={2};port={3};password={4};", mServer, mUid, mDatabase, mPort, mPassword);
public string SYSTEM_NAME { get; set; }
public dbConnetion()
{
Initilize_System_Settings();
}
// query the data base
public IEnumerable<T> getData<T>(string query, List<MySqlParameter> pars, Func<IDataRecord, T> transform)
{
using (var conn = new MySqlConnection(conn_string))
using (var cmd = new MySqlCommand(query, conn))
{
if (pars != null)
{
foreach (MySqlParameter p in pars)
{
cmd.Parameters.Add(p);
}
}
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return transform(rdr);
}
}
conn.Close();
}
}
// query the data base
public T getValue<T>(string query, List<MySqlParameter> pars)
{
T value;
using (var conn = new MySqlConnection(conn_string))
using (var cmd = new MySqlCommand(query, conn))
{
if (pars != null)
{
foreach (MySqlParameter p in pars)
{
cmd.Parameters.Add(p);
}
}
try
{
conn.Open();
object rawValue = cmd.ExecuteScalar();
if (rawValue != null)
{
value = (T)Convert.ChangeType(rawValue, typeof(T));
}
else
{
value = default(T);
}
}
catch (Exception ex)
{
Common.Alert(ex.ToString(), "SQL Error");
value = default(T);
}
finally
{
conn.Close();
}
}
return value;
}
public bool processQuery(string strSQL, List<MySqlParameter> pars)
{
bool toReturn = true;
using (var conn = new MySqlConnection(this.conn_string))
using (var cmd = new MySqlCommand(strSQL, conn))
{
foreach (MySqlParameter param in pars)
{
cmd.Parameters.Add(param);
}
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (MySqlException ex)
{
Common.Alert(ex.ToString(), "SQL Error");
toReturn = false;
}
finally
{
conn.Close();
}
}
return toReturn;
}
}
}
My first thoughts was to add a new parameter to the getData
method to allow me to not open/close connection if there is an open transaction, like this
// query the data base
public IEnumerable<T> getData<T>(string query, List<MySqlParameter> pars, Func<IDataRecord, T> transform, bool inTransaction = false)
{
using (var conn = new MySqlConnection(conn_string))
using (var cmd = new MySqlCommand(query, conn))
{
if (pars != null)
{
foreach (MySqlParameter p in pars)
{
cmd.Parameters.Add(p);
}
}
if(! inTransaction){
conn.Open();
}
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return transform(rdr);
}
}
if(! inTransaction){
conn.Close();
}
}
}
but I think this is not going to work because of the using
statement