I am doing a college attendance project with Winforms, MySQL, and C#.
In that I want to get or add "Users". So I wrote code for that:
public bool GetUser(ref clsConnection c)
{
MySqlCommand query = new MySqlCommand();
query.Connection = SQL;
query.CommandText = "SELECT ";
foreach (FieldInfo mi in typeof(clsConnection).GetFields())
{
foreach (StatsAttribute a in mi.GetCustomAttributes(typeof(StatsAttribute), false))
{
query.CommandText += a.Name + ", ";
}
}
query.CommandText = query.CommandText.Substring(0, query.CommandText.Length - 2);
query.CommandText += " FROM user WHERE User_Name='" + Escape(c.Username) + "'";
query.Prepare();
MySqlDataReader dr = query.ExecuteReader();
if (dr.HasRows)
{
foreach (FieldInfo mi in typeof(clsConnection).GetFields())
{
foreach (StatsAttribute a in mi.GetCustomAttributes(typeof(StatsAttribute), false))
{
dr.Read();
if (mi.FieldType.Name == "String")
{
mi.SetValue(c, (object)dr.GetString(a.Name));
}
else if (mi.FieldType.Name == "Double")
{
mi.SetValue(c, (object)dr.GetDouble(a.Name));
}
else if (mi.FieldType.Name == "Int32")
{
mi.SetValue(c, (object)dr.GetInt32(a.Name));
}
else if (mi.FieldType.Name == "UInt32")
{
mi.SetValue(c, (object)dr.GetUInt32(a.Name));
}
else if (mi.FieldType.Name == "Byte")
{
mi.SetValue(c, (object)dr.GetByte(a.Name));
}
else if (mi.FieldType.Name == "Boolean")
{
mi.SetValue(c, (object)dr.GetBoolean(a.Name));
}
else if (mi.FieldType.Name == "Date")
{
mi.SetValue(c, (object)dr.GetDateTime(a.Name));
}
}
}
}
else
{
dr.Close();
return false;
}
dr.Close();
return true;
}
public void AddUser(clsConnection c)
{
if (c.Username == "")
return;
List<string> users = new List<string>();
List<string> values = new List<string>();
int i = 0;
foreach (FieldInfo mi in typeof(clsConnection).GetFields())
{
foreach (StatsAttribute a in mi.GetCustomAttributes(typeof(StatsAttribute), false))
{
users.Add(a.Name);
values.Add("'" + mi.GetValue(c) + "'");
i++;
}
}
string query = "INSERT INTO user(" + string.Join(",", users.ToArray()) + ") VALUES (" + string.Join(",", values.ToArray()) + ");";
Query(query);
}
Im getting error with "The connection is open" when i try to connect with new or exist account. I can't find where is my problem... Probable somewhere is getuser or newuser im not closing data reader, but can't find where, please help me...
I am not sure if you close the connection here. Try with adding this after closing the "MySqlDataReader".
query.Connection.Close();
Also, you can see below an example;
https://dev.mysql.com/doc/dev/connector-net/8.0/html/M_MySql_Data_MySqlClient_MySqlCommand_ExecuteReader.htm
Related
I am attempting to create a database access layer. I am looking for some improvements to this class/recommendations on best practice. It would be helpful if someone could point me to documentation on how this could be potentially done/things to consider. I have looked at using entity framework but it does not seem applicable, however, should I really be looking to move to EF? Is ADO.NET an outdated way of doing this?
public static IDbCommand GetCommandObject(string Connstring)
{
IDbConnection conn = new SqlConnection(Connstring);
return new SqlCommand { Connection = (SqlConnection)conn };
}
public static void AddParameter(ref IDbCommand cmd, string Name, object value, DbType ParamType)
{
IDbDataParameter Param = cmd.CreateParameter();
Param.DbType = ParamType;
Param.ParameterName = (Name.StartsWith("#")) ? "" : "#"; //# character for MS SQL database
Param.Value = value;
cmd.Parameters.Add(Param);
}
public static Int32 ExecuteNonQuery(string SQL, IDbCommand cmd = null)
{
Boolean CommitTrans = true;
Boolean CloseConn = true;
SqlTransaction Trans = null;
try
{
//IF Required - create command object if required
if (cmd == null) { cmd = DB.GetCommandObject(""); }
//Add the commandtext
cmd.CommandText = SQL;
if (cmd.Connection == null) { throw new Exception("No connection set"); }
//IF REQUIRED - open the connection
if (cmd.Connection.State == ConnectionState.Closed)
{
cmd.Connection.Open();
}
else
{
CloseConn = false;
}
if (cmd.Transaction != null)
{
//We have already been passed a Transaction so dont close it
CommitTrans = false;
}
else
{
//Create and open a new transaction
Trans = (SqlTransaction)cmd.Connection.BeginTransaction();
cmd.Transaction = Trans;
}
Int32 rtn = cmd.ExecuteNonQuery();
if (CommitTrans == true) { Trans.Commit(); }
return rtn;
}
catch (Exception e)
{
if (CommitTrans == true) { Trans.Rollback(); }
throw new Exception();
}
finally
{
if (CloseConn == true)
{
cmd.Connection.Close();
cmd = null;
}
}
}
public static object ExecuteScalar(string SQL, IDbCommand cmd, Boolean NeedsTransaction = true)
{
Boolean CommitTrans = true;
Boolean CloseConn = true;
SqlTransaction Trans = null;
try
{
//IF Required - create command object if required
if (cmd == null) { cmd = DB.GetCommandObject(""); }
//Add the commandtext
cmd.CommandText = SQL;
//IF REQUIRED - create default Connection to CourseBuilder DB
if (cmd.Connection == null) { throw new Exception("No Connection Object"); }
//IF REQUIRED - open the connection
if (cmd.Connection.State == ConnectionState.Closed)
{
cmd.Connection.Open();
}
else
{
CloseConn = false;
}
if (NeedsTransaction == true)
{
if (cmd.Transaction != null)
{
//We have already been passed a Transaction so dont close it
CommitTrans = false;
}
else
{
//Create and open a new transaction
Trans = (SqlTransaction)cmd.Connection.BeginTransaction();
cmd.Transaction = Trans;
}
}
Object rtn = cmd.ExecuteScalar();
if (NeedsTransaction == true && CommitTrans == true) { Trans.Commit(); }
return rtn;
}
catch
{
if (NeedsTransaction == true && Trans != null) { Trans.Rollback(); }
throw new Exception();
}
finally
{
if (CloseConn == true) { cmd.Connection.Close(); cmd = null; }
}
}
public static DataRow GetDataRow(string SQL, IDbCommand cmd = null, Boolean ErrorOnEmpty = true)
{
var dt = FillDatatable(SQL, ref cmd);
if (dt.Rows.Count > 0)
{
return dt.Rows[0];
}
else
{
if (ErrorOnEmpty == true) { throw new Exception(nameof(GetDataRow) + " returned no rows."); }
return null;
}
}
public static DataTable FillDatatable(string SQL, ref IDbCommand cmd)
{
string newline = System.Environment.NewLine;
var DT = new DataTable();
Boolean LeaveConOpen = false;
try
{
//Add the commandtext
cmd.CommandText = SQL;
//IF REQUIRED - create default Connection to CourseBuilder DB
if (cmd?.Connection == null) { throw new Exception("No Connection Object"); }
if (cmd.Connection.State != ConnectionState.Open)
{
cmd.Connection.Open();
LeaveConOpen = false;
}
else
{
LeaveConOpen = true;
}
var DA = new SqlDataAdapter((SqlCommand)cmd);
DA.Fill(DT);
}
catch (Exception ex)
{
var sbErr = new StringBuilder();
sbErr.AppendLine("Parameters (type defaults to varchar(max)):" + newline);
foreach (SqlParameter p in cmd.Parameters)
{
string s = "";
sbErr.AppendLine("declare " + p.ParameterName + " varchar(max) = '" + (p.Value == DBNull.Value ? "Null" : p.Value + "'; ") + newline);
}
sbErr.AppendLine(newline + SQL + newline);
throw new Exception("Failed to FillDataTable:" + newline + newline + sbErr.ToString(), ex);
}
finally
{
if (LeaveConOpen == false) { cmd.Connection.Close(); }
}
return DT;
}
public static T CheckNull<T>(T value, T DefaultValue)
{
if (value == null || value is System.DBNull)
{
return DefaultValue;
}
else
{
return value;
}
}
Couple of things to keep in mind when you are creating a DAL
DAL should be able to cater to multiple Databases (oracle , sql , mysql etc..)
You should have minimum of DB , Connection , Command and Reader implementations of each.
Do not worry about the connection pool
Be aware of the transaction scope , Especially when you are trying to save nested objects. (For Eg: by saving company, you are saving Company and Company.Employees and Employee.Phones in a single transaction)
Alternative is to use something like Dapper.
enter image description here
I have bit of code in my program that will not let and operator start another batch until they finish the one that they are on but still allows another operator to start the same batch. The sqldatareader is returning the correct data i.e. 17080387-002 but the program keeps going to the "Please finish batch" step. I'm trying to figure out if it possibly has anything to do with how the batch is being returned.
public void BatchLockOut()
{
string eventID = null;
string batchLock = null;
string enteredLot = TextBoxLot.Text;
string connectionString = "";
string commandText = "SELECT BadgeNo, Container_ID, Event_ID, Event_Time " +
"FROM dbo.Custom_EventLog " +
"WHERE Event_Time IN (SELECT MAX(Event_Time) FROM dbo.Custom_EventLog WHERE BadgeNo = #BADGENO)";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(commandText, connection))
{
command.Parameters.Add("#BADGENO", SqlDbType.NChar, 10).Value = TextBoxLogin.Text;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
eventID = Convert.ToInt32(reader["Event_ID"]).ToString();
batchLock = reader["Container_ID"] as string;
break;
}
}
connection.Close();
}
if (batchLock == null)
{
ButtonBeginStir.IsEnabled = true;
}
else if (batchLock != enteredLot)
{
if (eventID == "1")
{
MessageBox.Show("Please finish previous stir", "Finish Stir", MessageBoxButton.OK, MessageBoxImage.Information);
ClearForm();
}
else
{
ButtonBeginStir.IsEnabled = true;
}
}
else if (batchLock == enteredLot)
{
if (eventID == "1")
{
ButtonEndStir.IsEnabled = true;
}
else if (eventID == "2")
{
ButtonBeginStir.IsEnabled = true;
}
}
}
I'm using SQLite with C#.
I use the following method to loop through a list of tv shows and their episodes and insert them into the database. It ends up entering about 1200 rows and takes 2 minutes 28 seconds. It feels like that's kinda slow so I would like people to look over my method and see if i'm doing something stupid (I'm sorta new to this).
public void InsertAllEpisodes(List<TVDBSharp.Models.Show> showList)
{
using (SQLiteConnection dbconnection = new SQLiteConnection(connectionString))
{
string seasonNumber;
string episodeNumber;
string insertShowSQL = #"INSERT INTO AllEpisodes (Key, ShowName, ShowId, EpisodeName, SeasonEpisode) VALUES (#Key, #ShowName, #ShowId, #EpisodeName, #SeasonEpisode)";
foreach (var show in showList)
{
foreach (var episode in show.Episodes)
{
if (episode.SeasonNumber != 0)
{
string seasonEpisode = "default";
if ((episode.SeasonNumber != 0) && (episode.SeasonNumber.ToString().Length == 1)) { seasonNumber = "0" + episode.SeasonNumber.ToString(); }
else { seasonNumber = episode.SeasonNumber.ToString(); }
if (episode.EpisodeNumber.ToString().Length == 1) { episodeNumber = "0" + episode.EpisodeNumber.ToString(); }
else { episodeNumber = episode.EpisodeNumber.ToString(); }
seasonEpisode = seasonNumber + episodeNumber;
SQLiteCommand command = new SQLiteCommand(insertShowSQL, dbconnection);
command.Parameters.AddWithValue("Key", show.Id + seasonEpisode);
command.Parameters.AddWithValue("ShowName", show.Name);
command.Parameters.AddWithValue("ShowId", show.Id);
command.Parameters.AddWithValue("EpisodeName", episode.Title);
command.Parameters.AddWithValue("SeasonEpisode", seasonEpisode);
dbconnection.Open();
try
{
command.ExecuteScalar();
}
catch (SQLiteException ex)
{
if (ex.ResultCode != SQLiteErrorCode.Constraint)
{
File.AppendAllText(programDataPath + "SQLErrors.txt", ex.Message + "\n");
}
}
dbconnection.Close();
}
}
}
}
}
I read up on and used sqlComm = new SQLiteCommand("begin", dbconnection) and sqlComm = new SQLiteCommand("end", dbconnection) and it inserted it in less than 1 second.
public void InsertAllEpisodes(List<TVDBSharp.Models.Show> showList)
{
using (SQLiteConnection dbconnection = new SQLiteConnection(connectionString))
{
dbconnection.Open();
string seasonNumber;
string episodeNumber;
string insertShowSQL = #"INSERT INTO AllEpisodes (Key, ShowName, ShowId, EpisodeName, SeasonEpisode) VALUES (#Key, #ShowName, #ShowId, #EpisodeName, #SeasonEpisode)";
SQLiteCommand sqlComm;
sqlComm = new SQLiteCommand("begin", dbconnection);
sqlComm.ExecuteNonQuery();
foreach (var show in showList)
{
foreach (var episode in show.Episodes)
{
if (episode.SeasonNumber != 0)
{
string seasonEpisode = "default";
if ((episode.SeasonNumber != 0) && (episode.SeasonNumber.ToString().Length == 1)) { seasonNumber = "0" + episode.SeasonNumber.ToString(); }
else { seasonNumber = episode.SeasonNumber.ToString(); }
if (episode.EpisodeNumber.ToString().Length == 1) { episodeNumber = "0" + episode.EpisodeNumber.ToString(); }
else { episodeNumber = episode.EpisodeNumber.ToString(); }
seasonEpisode = seasonNumber + episodeNumber;
sqlComm = new SQLiteCommand(insertShowSQL, dbconnection);
sqlComm.Parameters.AddWithValue("Key", show.Id + seasonEpisode);
sqlComm.Parameters.AddWithValue("ShowName", show.Name);
sqlComm.Parameters.AddWithValue("ShowId", show.Id);
sqlComm.Parameters.AddWithValue("EpisodeName", episode.Title);
sqlComm.Parameters.AddWithValue("SeasonEpisode", seasonEpisode);
try
{
sqlComm.ExecuteScalar();
}
catch (SQLiteException ex)
{
if (ex.ResultCode != SQLiteErrorCode.Constraint)
{
File.AppendAllText(programDataPath + "SQLErrors.txt", ex.Message + "\n");
}
}
}
}
}
sqlComm = new SQLiteCommand("end", dbconnection);
sqlComm.ExecuteNonQuery();
dbconnection.Close();
}
}
Can somebody help understand this code?
protected void Page_Load(object sender, EventArgs e)
{
Database database = new Database();
OleDbConnection conn = database.connectDatabase();
if (Request.Cookies["BesteldeArtikelen"] == null)
{
lbl_leeg.Text = "Er zijn nog geen bestelde artikelen";
}
else
{
HttpCookie best = Request.Cookies["BesteldeArtikelen"];
int aantal_bestel = best.Values.AllKeys.Length;
int[] bestelde = new int[aantal_bestel];
int index = 0;
foreach (string art_id in best.Values.AllKeys)
{
int aantalbesteld = int.Parse(aantalVoorArtikel(int.Parse(art_id)));
int artikel_id = int.Parse(art_id); // moet getalletje zijn
if (aantalbesteld != 0)
{
bestelde[index] = artikel_id;
}
index++;
}
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT artikel_id, naam, prijs, vegetarische FROM artikel WHERE artikel_id IN (" +
String.Join(", ", bestelde) + ")";
try
{
conn.Open();
OleDbDataReader reader = cmd.ExecuteReader();
GridView1.DataSource = reader;
GridView1.DataBind();
}
catch (Exception error)
{
errorMessage.Text = error.ToString();
}
finally
{
conn.Close();
}
}
}
And there is this part of code i dont really understand:
public string aantalVoorArtikel(object id)
{
int artikel_id = (int)id;
if (Request.Cookies["BesteldeArtikelen"] != null &&
Request.Cookies["BesteldeArtikelen"][artikel_id.ToString()] != null)
{
return Request.Cookies["BesteldeArtikelen"][artikel_id.ToString()];
}
else
{
return "0";
}
}
It extracts values from a cookie and builds an int array. (Displays a message if the cookie value is null) The int array is then used as the value for the SQL IN operator when querying the database. The result set is then bound to the GridView.
My registration program logs people in with their name, id and "Time In:" when they scan themselves in, and hides them, but adds "Time Out: " to their name, and vice versa. What im looking to do is every time the person scans themselves "In" I want it to look at the Time "In"'s amd "out"'s and calculate thr total time IN the office.
Attached is the code :
private string CreateTimeEntry(string current)
{
var indexIn = current.LastIndexOf("Time In : "); // Get the last index of the word "in"
var indexOut = current.LastIndexOf("Time Out : "); // Get the last index of the word out
string timeIn = current + " " + "Time In : ";
string timeOut = current + " " + "Time Out : ";
if (indexOut > indexIn)
{
// if the last "out" comes after the last "in"
return timeIn;
}
else
{
// If the last "in" comes after the last "out"
return timeOut;
}
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
SqlConnection DBConnection = new SqlConnection("Data Source=DATABASE;Initial Catalog=imis;Integrated Security=True");
SqlCommand cmd = new SqlCommand();
Object returnValue;
string txtend = textBox1.Text;
if (e.KeyChar == 'L')
{
DBConnection.Open();
}
if (DBConnection.State == ConnectionState.Open)
{
if (textBox1.Text.Length != 6) return;
{
cmd.CommandText = ("SELECT last_name +', '+ first_name from name where id =#Name");
cmd.Parameters.Add(new SqlParameter("Name", textBox1.Text.Replace(#"L", "")));
cmd.CommandType = CommandType.Text;
cmd.Connection = DBConnection;
returnValue = cmd.ExecuteScalar() + "\t (" + textBox1.Text.Replace(#"L", "") + ")";
DBConnection.Close();
bool found = false;
System.DateTime resultTime1 = new System.DateTime(;
foreach (var item in listBox1.Items)
{
var itemEntry = item.ToString();
string newEntry = CreateTimeEntry(itemEntry) + DateTime.Now.ToString("HH:mm") + " " + "Total Time: " + resultTime1 ;
if (itemEntry.Contains(returnValue.ToString()))
{
var indexIn = itemEntry.LastIndexOf("Time In : ");
var indexOut = itemEntry.LastIndexOf("Time Out : ");
if (indexOut > indexIn)
{
listBox2.Items.Remove(item);
listBox1.Items.Add(newEntry);
found = true;
break;
}
else
{
listBox1.Items.Remove(item);
listBox2.Items.Add(newEntry);
found = true;
break;
}
}
}
if (!found)
{
string newEntry2 = "";
foreach (string str in listBox2.Items)
{
var itemEntry2 = str;
newEntry2 = CreateTimeEntry(itemEntry2) + DateTime.Now.ToString("HH:mm");
//if (listBox2.Items.Contains(returnValue.ToString()))
if (listBox2.Items.Contains(str) && str.Contains(textBox1.Text))
{
var indexIn = itemEntry2.LastIndexOf("Time In : ");
var indexOut = itemEntry2.LastIndexOf("Time Out : ");
if (indexOut > indexIn)
{
listBox2.Items.Remove(str);
listBox1.Items.Add(newEntry2);
found = true;
break;
}
}
}
var itemEntry = listBox1.Items.ToString();
var itemEntry1 = listBox2.Items.ToString();
if (!listBox1.Items.Contains(newEntry2))
{
listBox1.Items.Add(returnValue + " " + "Time In : " + DateTime.Now.ToString("HH:mm"));
}
}
}
textBox1.Clear();
System.IO.StreamWriter SaveFile = new System.IO.StreamWriter(fullFileName);
foreach (object item1 in listBox1.Items)
SaveFile.WriteLine(item1.ToString());
SaveFile.Flush();
SaveFile.Close();
if (listBox1.Items.Count != 0) { DisableCloseButton(); }
else
{
EnableCloseButton();
}
Current_Attendance_Label.Text = "Currently " + listBox1.Items.Count.ToString() + " in attendance.";
e.Handled = true;
}
You can get the difference between two DateTime objects using the following:
TimeSpan timePassed = timeOut.Subtract(timeIn);
where timeOut and timeIn are DateTime objects.
If you need the difference (or either of the times) displayed somewhere as a string, I would recommend converting them to strings only after doing the calculations that you need. Always work with strongly typed objects when possible.