Why the while loop is used in this database connection? - c#

Currectly I am studying and learning and I just wanted to know some logic of this database connection in C#. I wanted to know why the while loop is used I means if I don't use it, will it affect the program or will the program run fine if I take it out. I just wanted to know is it wise to use it or just take it out from the program. Can someone please help me ?? Thank you
private bool filled;
public DataSet ds = new DataSet();
private void bnt_displaylog_Click(object sender, EventArgs e)
{
try
{
string dbconnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Elevator_Database.accdb;";
string dbcommand = "Select * from Log;";
OleDbConnection conn = new OleDbConnection(dbconnection);
OleDbCommand comm = new OleDbCommand(dbcommand, conn);
OleDbDataAdapter adapter = new OleDbDataAdapter(comm);
conn.Open();
//MessageBox.Show("Connection Open ! ");
**while (filled == false)**
{
adapter.Fill(ds);
filled = true;
}
conn.Close();
}
catch (Exception)
{
MessageBox.Show("Can not open connection ! ");
string message = "Error in connection to datasource";
string caption = "Error";
MessageBoxButtons buttons = MessageBoxButtons.OK;
DialogResult result;
result = MessageBox.Show(message, caption, buttons);
}
database_listbox.Items.Clear();
foreach (DataRow row in ds.Tables[0].Rows)
{
database_listbox.Items.Add(row["Date"] + "\t\t" + row["Time"] + "\t\t" + row["Action"]);
}
}

That's just code that was written in a very unclear manner. The while loop will never loop at all. The loop body will either be executed once, or not at all, depending on the value of filled.
In other words, the code could have been written more clearly as:
conn.Open();
if( ! filled )
{
adapter.Fill(ds);
filled = true;
}
conn.Close();
But even then, the code is doing the wrong thing. Think about the case where filled is true. The code that's actually executed is:
conn.Open();
conn.Close();
and what's the point of doing that?
In any case, what the code actually does, either with while or if, is call adapter.Fill(ds) only the first time through. Given that, we should skip setting up the connection entirely when we don't make that call. And let's refactor the code to make it a bit more clear:
private bool filled = false;
public DataSet ds = new DataSet();
private void bnt_displaylog_Click(object sender, EventArgs e)
{
loadDisplayLog();
database_listbox.Items.Clear();
foreach (DataRow row in ds.Tables[0].Rows)
{
database_listbox.Items.Add(
row["Date"] + "\t\t" + row["Time"] + "\t\t" + row["Action"]
);
}
}
private void loadDisplayLog(object sender, EventArgs e)
{
if( filled ) return;
try
{
string dbconnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Elevator_Database.accdb;";
string dbcommand = "Select * from Log;";
OleDbConnection conn = new OleDbConnection(dbconnection);
OleDbCommand comm = new OleDbCommand(dbcommand, conn);
OleDbDataAdapter adapter = new OleDbDataAdapter(comm);
conn.Open();
adapter.Fill(ds);
conn.Close();
filled = true;
}
catch (Exception)
{
MessageBox.Show("Can not open connection ! ");
string message = "Error in connection to datasource";
string caption = "Error";
MessageBoxButtons buttons = MessageBoxButtons.OK;
DialogResult result;
result = MessageBox.Show(message, caption, buttons);
}
}
There are still some issues with the exception handling in this code - will the connection be closed if adapter.Fill(ds); throws an exception? Oops. But I'll leave the rest as an exercise for the reader...

Related

Datagrid view not populating when mysql parameters are used

My thinking is that the problem lies with the adapter. However, I'm still very green and would appreciate any help. I've searched this forum and have had no luck with any of the resolutions I've found (pebkac probably). The application is simple, use textbox input in a parameterized select statement to populate the datagridview. The query will execute but the grid remains empty. VS2017, MySql8.0
private void button2_Click(object sender, EventArgs e)
{
string myConnectionstring = null;
string mySelect = "SELECT * FROM part_data WHERE 'SERIAL' = #test; ";
string tb7 = textBox7.Text;
//Set Connection String And Create Connection
myConnectionstring = "server=localhost;user= admin; database= trace;port=3306;password= admin;Allow User Variables=True";
DataSet ds = new DataSet();
using (MySqlConnection myConnection = new MySqlConnection(myConnectionstring))
{ //Create Command Object
//MySqlCommand myCommand = new MySqlCommand(mySelect, myConnection);
try
{
myConnection.Open();
// myCommand.Prepare();
//myCommand.Parameters.AddWithValue("#test",tb7);
MySqlDataAdapter adapter = new MySqlDataAdapter(mySelect, myConnectionstring);
adapter.SelectCommand.Parameters.AddWithValue("#test",tb7);
//debug to see final select statement
richTextBox1.Text = mySelect;
adapter.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show("Query Failed" + ex);
}
}
At first glance it looks as though your query might be bad. Try using backticks around the column name.
SELECT * FROM part_data WHERE `SERIAL` = #test;
Try making the query without parameters, there is no need to do it like that, then try the DataSourceView of your dataset.

C# datagridview shound not change until there is a result

Recently i developed a search function, but i want when a user inputs something on the textbox the datagridview to not go blank but instead to show the data that it already has and when the result is found than only show the result. Because now when i type anything on the search textbox the dgv immediately goes blank.
Here is my code:
private void txtBarkod_TextChanged(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtBarkod.Text)) {
resetTxTboxes();
}
MySqlConnection connection = Connection.prevzemiKonekcija();
try {
connection.Open();
MySqlCommand command;
MySqlDataAdapter adapter;
DataTable tabela;
string query = "SELECT * FROM artikli WHERE barcode like '%" + txtBarkod.Text + "%'";
command = new MySqlCommand(query, connection);
adapter = new MySqlDataAdapter(command);
tabela = new DataTable();
adapter.Fill(tabela);
dataGridView1.DataSource = tabela;
if (txtBarkod.Text == "") {
ShowDgV();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
connection.Close();
}
}
Reset/Rebind the datasource of your datagridview only if you found something in your db.
if(tabela.Rows.Count > 0)
{
dataGridView1.DataSource = tabela;
}

WPF Form freezing up

Ok - I have finally got my connection string and sql string correct in this WPF form. I kept getting reader exceptions until I finally got the sql string the correct way, so since I am not getting errors now - I am assuming it is correct. Have inserted a breakpoint at IDbCommand and stepped through, and all steps seem to go fine. But the program locks up and does not display any data in the datagrid. Cannot even click on the form once all statements are processed. What have I missed here?
This is a Progress OpenEdge DB - and this is the recommended connection and command from Progress.
private void MonReadButton_Click(object sender, RoutedEventArgs e)
{
var estNum = EstTextBox.Text;
{
string connectString = "DSN=****;uid=**;pwd=*****;host=****;port=****;db=****;";
using (OdbcConnection dbConn = new OdbcConnection(connectString))
{
try
{
dbConn.Open();
}
catch (Exception)
{
MessageBox.Show("connection failed");
}
IDbCommand dbcmd = dbConn.CreateCommand();
string sqlstr = #"SELECT ""Estimate"".""Labor-Cost"" FROM ""GAMS1"".""PUB"".""Estimate"" WHERE ""Estimate"".""Estimate-ID""=" + estNum;
dbcmd.CommandText = sqlstr;
IDataReader reader = dbcmd.ExecuteReader();
while (reader.Read())
{
DataTable dt = new DataTable();
dt.Load(reader);
DataGrid1.ItemsSource = dt.DefaultView;
}
reader.Close();
reader = null;
dbcmd.Dispose();
dbcmd = null;
dbConn.Close();
}
}
}

Refreshing the combobox after inserting data in mysql c#

Hello so i want to refresh my combobox after i add or delete data from it now if i add data it doesnt get refreshed i have to rerun the program to see the changes but i want to get it refresh in the time i add the data..
the code when i add data:
private void button5_Click(object sender, EventArgs e)
{
MySqlConnection dataConnection = new MySqlConnection();
dataConnection.ConnectionString = "datasource=localhost;port=3306;username=root;password=";
dataConnection.Open();
MySqlTransaction transakcija = dataConnection.BeginTransaction();
MySqlCommand dataCommand = new MySqlCommand();
dataCommand.Connection = dataConnection;
dataCommand.Transaction = transakcija;
try
{
dataCommand.CommandText = "Insert INTO filmi.film (film) VALUES ('" + this.tB_Dodaj.Text + "')";
dataCommand.CommandType = CommandType.Text;
dataCommand.ExecuteNonQuery();
transakcija.Commit();
MessageBox.Show("You added a new movie!");
}
catch (Exception eks)
{
transakcija.Rollback();
MessageBox.Show("Movie couldnt be added!!\n" + eks.Message);
}
finally
{
dataCommand.Connection.Close();
}
}
and with each insert the data gets displayed in the combobox but only when i rerun the program
this is how i fill combobox:
void Fillcombo()
{
string constring = "datasource=localhost;port=3306;username=root;password=";
string Query = "SELECT * FROM filmi.film ;";
MySqlConnection conDataBase = new MySqlConnection(constring);
MySqlCommand cmdDataBase = new MySqlCommand(Query, conDataBase);
MySqlDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
while (myReader.Read())
{
string sName = myReader.GetString("film");
comboBox1.Items.Add(sName);
comboBox2.Items.Add(sName);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
i have to rerun the program to see the changes but i want to get it
refresh in the time i add the data..
I suspect that you are calling the Fillcombo() method in Form_Load event handler.
if you want to update the combobox for every insert and delete operations in your table you need to call Fillcombo() immediatly after executing the command.
Try This:
int status = dataCommand.ExecuteNonQuery();
transakcija.Commit();
if(status > 0)
{
Fillcombo();
MessageBox.Show("You added a new movie!");
}
in your FillCombo clear the items before adding the new items to remove the duplicates.
comboBox1.Items.Clear(); //add this statetement before adding items
comboBox2.Items.Clear(); //add this statetement before adding items
while (myReader.Read())
{
string sName = myReader.GetString("film");
comboBox1.Items.Add(sName);
comboBox2.Items.Add(sName);
}
ADO.NET object works in a disconnected state, so, adding a record to your datatable doesn't automatically shows up in your combo. You need to call again FillCombo, (clearing the items already in combos, going again to the database to retrieve every record again, adding them to your comboboxes) or just simply adding the film to your already filled combos as a single item
Also pay attention to Sql Injection (use always a parameterized query)
private void button5_Click(object sender, EventArgs e)
{
string conString = "datasource=localhost;port=3306;username=root;password=";
string cmdText = "Insert INTO filmi.film (film) VALUES (#film)";
using(MySqlConnection dataConnection = new MySqlConnection(conString))
using(MySqlCommand dataCommand = new MySqlCommand(cmdText, dataConnection))
{
try
{
dataConnection.Open();
dataCommand.Parameters.AddWithValue("#film", this.tB_Dodaj.Text);
// If ExecuteNonQuery returns a value > 0 then your record has been inserted
// Just add the name of the film to the two combos
if(dataCommand.ExecuteNonQuery() > 0)
{
MessageBox.Show("You added a new movie!");
comboBox1.Items.Add(this.tB_Dodaj.Text);
comboBox2.Items.Add(this.tB_Dodaj.Text);
}
}
catch(Exception ex)
{
MessageBox.Show("Fail to add a new movie! " + ex.Message);
}
}
}
As a last note, watch carefully your fillcombo method. You don't close and dispose the connection.

CombBox is not populating the ValueMember Properly from MySQL in C#

I have two combobox in my form, using a mysql connection to a remote server. The first combobox populated nicely. However, I need the indexid since that is a foreign key to populate a second combobox. Based on the selection, it will change the data in the second combo (for the xample, i the first combo is for car makes, then the models of each make gets filled, so if I choose Nissan, the models will then have Altima, Maxima, Sentra, ... but if I chose Toyota, the combo will then show Corolla, Camry, Prius, ...)
My foreign key is always -1 for some reason. I am using the selectindex change method, but it keeps crashing/ bc the value is always -1.
I am very new to MySQL in C# and eager to learn. Any help is appreciated. The code is below.
private void cboMake_SelectedIndexChanged(object sender, EventArgs e)
{
if (cboMake.SelectedIndex >= 0)
cboModel.Enabled = true;
else
cboModel.Enabled = false;
// get the foreign key value of the model id to get the make for each brand to populate here
// MessageBox.Show(cboModel.ValueMember);
// right now selectindex always shows -1. why?
// if it changes, you need to then enable the right cbo, else, disable.
// but also, you need the mid, fk, so you can then do a new sql statement with the where clause to populate it.
int fk = cboModel.SelectedIndex;
string connStr = "server=123.456.7.8;user=root;database=car;port=3306; password=nowayjose";
MySqlConnection conn = new MySqlConnection(connStr);
try
{
string sql = "SELECT * FROM cs_model WHERE mid='fk'";
MySqlCommand cmd = new MySqlCommand(sql, conn);
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
cboMake.DataSource = dt;
cboMake.DisplayMember = "model";
cboMake.ValueMember = "mmid";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "MySQL Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
conn.Close();
}
private void frmMain_Load(object sender, EventArgs e)
{
string connStr = "server=123.456.7.8;user=root;database=car;port=3306; password=nowayjose";
MySqlConnection conn = new MySqlConnection(connStr);
try
{
string sql = "SELECT * FROM cs_make";
MySqlCommand cmd = new MySqlCommand(sql, conn);
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
cboMake.DataSource = dt;
cboMake.DisplayMember = "make";
cboMake.ValueMember = "mid";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "MySQL Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
conn.Close();
}
Correct me if I'm wrong, but considering code provided, just a guess :
private void cboMake_SelectedIndexChanged(object sender, EventArgs e)
{
int fk = cboModel.SelectedIndex; // ?????
.....
}
You access here cboModel, which is not that one whom item was actually selected. At least lookin on event name cboMake_SelectedIndexChanged, seems to me that you should look on cboMake selected index.
Hope this helps.
private void cboMake_SelectedIndexChanged(object sender, EventArgs e)
{
int foreignKey = (int)cboMake.SelectedIndex +1; // i forgot to cast the int from string since the database was tinyint, it still returns string in c#
string fk = foreignKey.ToString(); // since i need the string for the query, back it goes, but i needed to do arithmetic
string connStr = "server=10.18.30.1;user=notroot;database=car;port=3306;password=password";
MySqlConnection conn = new MySqlConnection(connStr);
try
{
string sql = "SELECT * FROM cs_model WHERE mid=" + fk; // forgot to escape out of the string (used to php $var style within double quotes)
MySqlCommand cmd = new MySqlCommand(sql, conn);
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
cboModel.DataSource = dt; // i had cboModel by a silly mistake
cboModel.DisplayMember = "model";
cboModel.ValueMember = "mmid";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "MySQL Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
conn.Close();
}

Categories