Currently my team is building an application involving a database. We have to write a lot of data (approx 2,000,000 records) to the database and therefore we decided to open a connection once and close it afterwards. The connection will become a local connection, so we don't have to worry about unwanted intruders that much.
The code works as it is supposed to, however we are trying to make sure every little bit is optimized to make it as efficient as possible. Is there anything that could be done better?
public class Database
{
/// <summary>
/// The connection which is established when connecting to the database.
/// </summary>
private MySqlConnection _conn;
/// <summary>
/// A command which can be used to execute queries.
/// </summary>
private MySqlCommand _cmd;
/// <summary>
/// The private singleton instance of the database.
/// </summary>
private static Database _instance;
/// <summary>
/// The constructor.
/// </summary>
private Database() {}
/// <summary>
/// The public singleton instance of the database
/// </summary>
public static Database Instance
{
get
{
if (_instance == null)
{
//Create a new instance if it is not already done.
_instance = new Database();
}
return _instance;
}
}
/// <summary>
/// Return whether the connection is open or not.
/// </summary>
public bool isConnected
{
get { return _conn.State == ConnectionState.Open; }
}
/// <summary>
/// This method will let the user connect to the database with a given connection string.
/// </summary>
/// <param name="conStr">The connection string</param>
public void Connect(string conStr)
{
//Make the connection
_conn = new MySqlConnection(conStr);
//Open the connection
_conn.Open();
}
/// <summary>
/// This method will let the user connect to the database given specific values.
/// </summary>
/// <param name="ip">The IP-address of the database (127.0.0.1 for local)</param>
/// <param name="db">The name of the database</param>
/// <param name="uid">The user ID</param>
/// <param name="pw">The password</param>
public void Connect(string ip, string db, string uid, string pw)
{
//Make the connection
_conn = new MySqlConnection(@"Data Source=" + ip + ";Database=" + db + ";Uid=" + uid + ";Pwd=" + pw + ";Allow User Variables=True");
//Open the connection
_conn.Open();
}
/// <summary>
/// This method will execute the given query and will return the result given from the database
/// </summary>
/// <param name="query">The query</param>
/// <returns>The result given from the database</returns>
public DataTable Read(string query)
{
DataTable _resultTable = new DataTable();
//Only procede if there is a connection. Return null otherwise.
if (_conn == null)
{
return null;
}
//Create the command with the gien query
_cmd = new MySqlCommand(query, _conn);
//We need MySqlDataAdapter to store all rows in the datatable
using (MySqlDataAdapter adapter = new MySqlDataAdapter(_cmd))
{
adapter.Fill(_resultTable);
}
//Return the result.
return _resultTable;
}
}
Clarification
- The
_cmd
is only created once and henceprivate
. We use thisMySqlCommand
multiple times in multiple methods, and therefore we reuse_cmd
every time. - The
_conn
is only created once since we only want to make one connection. - The use of
MySqlDataAdapter
is on purpose, becauseDataTable.Load(_cmd.ExecuteReader())
method will overwrite rows when multiple corresponding primary keys are given by a query.
There are more methods that involve the creation of INSERT
and DELETE
queries, but they are not of any use here.
Note: We encourage the use of comments in the code since we are recruiting new team members and therefore we want to make the code more readable. I added the comments in my post, but if you want me to delete them, tell me so.