I am having trouble with the following line:
MySqlDataReader DataReader = objDatabase.SetCommandType("GetRaceLevels").ExecuteReader();
It keeps returning the following error:
System.InvalidOperationException: 'Connection must be valid and open.'
private void RegisterForm_Load(object sender, EventArgs e)
{
HideMe();
MoveMe(-180);
MySqlConnection myConnection = objDatabase.GetConnection(); //must save the object based connection to a local variable for some reason.
myConnection.Open();
MySqlDataReader DataReader = objDatabase.SetCommandType("GetRaceLevels").ExecuteReader();
try
{
while (DataReader.Read())
{
cboRunnerTypes.Items.Add(DataReader[1]);
}
}
catch (Exception ex)
{
MessageBox.Show("Critical error!");
}
myConnection.Close();
}
I have tested the connection, it does work just fine, and it works during my login process.
The only other thing is this whole process utilises my clsDatabase class, that is where MySqlDataReader DataReader = objDatabase.SetCommandType("GetRaceLevels").ExecuteReader(); comes from.
This is the function on the clsDatabse class:
public MySqlCommand SetCommandType(string sProcedureName)
{
MySqlCommand myCommand = new MySqlCommand(sProcedureName, GetConnection()); //I think the problem is here, how am I fixing it though?
myCommand.CommandType = CommandType.StoredProcedure;
return myCommand;
}
I hope this all makes sense and I am not being extremely thick. Any help would be much appreciated! Thank you!
EDIT: The class:
class clsDatabase
{
private const string conString = "server = ; database = ; user = ; password = ; charset = utf8";
public MySqlConnection GetConnection()
{
MySqlConnection myConnection = new MySqlConnection(conString);
return myConnection;
}
public void EmailCommandCaller(MySqlCommand myCommand, string sEmail, string sContent)
{
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue(sEmail, sContent);
}
public void LoginCommandCaller(MySqlCommand myCommand, string sEmail, string sPassword, string sEmailContent, string sPasswordConetnt)
{
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue(sEmail, sEmailContent);
myCommand.Parameters.AddWithValue(sPassword, sPasswordConetnt);
}
public MySqlCommand SetCommandType(string sProcedureName)
{
MySqlCommand myCommand = new MySqlCommand(sProcedureName, GetConnection()); //I think the problem is here, how am I fixing it though?
myCommand.CommandType = CommandType.StoredProcedure;
return myCommand;
}
}
Everytime you call GetConnection() you're getting a brand new one. A new connection starts closed. Now, look at your SetCommandType method. It's instancianting a new MySqlCommand with a brand new connection, which is closed. You could open the connection in the method, but that is error prone, as you would end up with no means to close the connection afterward. Instead, instantiate the connection where you want to use it. Also, use using statements for better IDisposable handling.
private void RegisterForm_Load(object sender, EventArgs e)
{
HideMe();
MoveMe(-180);
using(MySqlConnection myConnection = new MySqlConnection(conString)){
myConnection.Open();
MySqlCommand myCommand = new MySqlCommand("GetRaceLevels", myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
using(MySqlDataReader DataReader = myCommand.ExecuteReader()){
try
{
while (DataReader.Read())
{
cboRunnerTypes.Items.Add(DataReader[1]);
}
}
catch (Exception ex)
{
MessageBox.Show("Critical error!");
}
}
}
}
Related
Okey, so I am new to C# and I have tried to move my Mysql connection string to another class but I can't seem to open the connection once I call the method and I really can't see what's wrong.
So this is the connection method in a new class(DatabaseC)
public static void Connection()
{
try
{
ConnectionStringSettings conSettings = ConfigurationManager.ConnectionStrings["cs"];
string conn = conSettings.ConnectionString;
MySqlConnection connect = new MySqlConnection(conn);
connect.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
And here I call the method in a Form
private bool validate_login(string u, string p)
{
DatabaseC.Connection();
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "SELECT * FROM account WHERE Password COLLATE latin1_general_cs = #password AND User COLLATE latin1_general_cs = #username";
cmd.Parameters.AddWithValue("#username", u);
cmd.Parameters.AddWithValue("#password", p);
MySqlDataReader login = cmd.ExecuteReader();
}
Sorry for if the code looks bad but as I said im new.
You should return the instance of the MySqlConnection opened
public static MySqlConnection Connection()
{
ConnectionStringSettings conSettings = ConfigurationManager.ConnectionStrings["cs"];
string conn = conSettings.ConnectionString;
MySqlConnection connect = new MySqlConnection(conn);
connect.Open();
return connect;
}
Now you can change your calling code to receive the connection and use it
private bool validate_login(string u, string p)
{
using(MySqlConnection cnn = DatabaseC.Connection())
using(MySqlCommand cmd = cnn.CreateCommand())
{
cmd.CommandText = "......"
...
using(MySqlDataReader reader = cmd.ExecuteReader())
{
.....
} // Here the reader is closed and destroyed
} // Here the connection closed and destroyed with the command
}
Notice that a connection is a disposable object and thus you should be sure to destroy it once you have finished to use it. This is the work of the using statement.
Another problem fixed with this code is the fact that a command needs to know the connection to use, your actual code doesn't link the command with the connection and thus it cannot work.
EDIT: you comment below should be added to the answer. The Try/Catch in the Connection method should be removed. You do nothing there and catching the exception creates only complications in the calling code that need to handle a null return value. It is better to let the exception bubble up until there is a method that has something to do with that (like logging it for example)
Actually you need to open the connection where you are using the connection, try this way
public static MySqlConnection Connection()
{
try
{
ConnectionStringSettings conSettings = ConfigurationManager.ConnectionStrings["cs"];
string conn = conSettings.ConnectionString;
MySqlConnection connect = new MySqlConnection(conn);
return connect;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
then
private bool validate_login(string u, string p)
{
DatabaseC.Connection().Open();
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "SELECT * FROM account WHERE Password COLLATE latin1_general_cs = #password AND User COLLATE latin1_general_cs = #username";
cmd.Parameters.AddWithValue("#username", u);
cmd.Parameters.AddWithValue("#password", p);
MySqlDataReader login = cmd.ExecuteReader();
I´m asking how to connect two or more tables from an MS Access table into c# Windows forms?.
I get the error, that ue cant find the second table:
public partial class Form1 : Form
{
private OleDbConnection connection = new OleDbConnection();
private OleDbConnection connection2 = new OleDbConnection();
public Form1()
{
connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\be\Documents\MitarbeiterDaten2.accdb;
Persist Security Info=False;";
connection2.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\be\Documents\DatenbankAbteilung.accdb;
Persist Security Info=False;";
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
string query = "select ABTEILUNG from combo";
command.CommandText = query;
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Abteilung.Items.Add(reader["ABTEILUNG"].ToString());
}
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
}
finally
{
connection.Close();
}
Anybody got an solution?
Its just about, how to connect two or more MS Access tables into C# Windows forms.
You can reuse the the objects, and can get data from various tables or databases, as :
private void Form1_Load(object sender, EventArgs e)
{
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
string query = "select ABTEILUNG from combo";
command.CommandText = query;
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Abteilung.Items.Add(reader("ABTEILUNG").ToString());
}
reader.Close(); //' Always Close ther Reader. Don't left it open
connection2.Open();
command.Connection = connection2; //' Reusing Same Command Over New Connection
command.CommandText = "Select Field2 from Table2";
while (reader.Read)
{
if (!(Convert.IsDBNull(reader("Field2")))) //' Checking If Null Value is there
{
Abteilung.Items.Add(reader("Field2").ToString());
}
}
reader.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
}
finally
{
connection.Close();
connection2.Close();
}
}
How about using using blocks to take care of the commands and connections and then using DataAdapter to get the job done easily. I use some code like this.
DataSet ds = new DataSet();
using (OleDbConnection con = new OleDbConnection(MDBConnection.ConnectionString))
{
con.Open();
using (OleDbCommand cmd = new OleDbCommand("SELECT Column FROM Table1", con))
{
using (OleDbDataAdapter da = new OleDbDataAdapter(cmd))
{
da.Fill(ds);
}
}
using (OleDbCommand cmd = new OleDbCommand("SELECT AnotherColumn FROM Table2", con))
{
using (OleDbDataAdapter da = new OleDbDataAdapter(cmd))
{
da.Fill(ds);
}
}
}
return ds;
namespace PCMS
{
public partial class frmPlayerInterface : Form
{
private OleDbConnection con = new OleDbConnection();
OleDbCommand com = new OleDbCommand();
private DataTable dt = new DataTable();
public frmPlayerInterface(string getUser)
{
InitializeComponent();
con.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\Projects\SDP\PCMS\SDP.accdb";
lblUser.Text = getUser;
}
private void btnEnquire_Click(object sender, EventArgs e)
{
frmEnquire frmenq = new frmEnquire();
frmenq.ShowDialog();
}
private void btnTopUp1_Click(object sender, EventArgs e)
{
frmTopUp frmTU = new frmTopUp();
frmTU.ShowDialog();
}
private void frmPlayerInterface_Load(object sender, EventArgs e)
{
con.Open();
OleDbCommand comm = new OleDbCommand();
String sql = "select Balance from PlayerAccount where Player_User=#user";
comm.Parameters.Add(new OleDbParameter("user", lblUser.Text));
comm.CommandText = sql;
OleDbDataReader cursor = comm.ExecuteReader();
while (cursor.Read())
{
lblBalance.Text = cursor["Balance"].ToString();
}
con.Close();
}
}
}
Hey sorry guys asking this again but ive been trying this for the past three hours and wave the white flag. Still getting the same error.
I just want to have the selected balance value from the database to be shown in the label.
Thanks ><
You're not associating the connection with the command object:
con.Open();
String sql = "select Balance from PlayerAccount where Player_User=#user";
OleDbCommand comm = new OleDbCommand(sql, con);
Note that reusing a connection is not always the best design. Connections are pooled in .NET, so recreating them is generally not an expensive operation. A better design would be to store the connection string as a class property then just create a connection when you need it:
private string ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\Projects\SDP\PCMS\SDP.accdb";
// or better yet - pull form app.config...
and when you use it:
String sql = "select Balance from PlayerAccount where Player_User=#user";
using(OleDbConnection con = new OleDbConnection(ConnectionString))
{
con.Open();
using(OleDbCommand comm = new OleDbCommand(sql, con))
{
... Add parameters, execute query, return results
}
}
I have written some C# to update a MySql table but I get an exception every time I call the method ExecuteNonQuery(). I have researched this on the web and every solution I find produces the same error. I have an open connection to the database and the update query to the database is written correctly. The code that I have so far come up with is :
public int executeUpdate()
{
int result = 0;
if (isConnected)
{
try
{
MySqlConnection cn = new MySqlConnection(connection.ConnectionString);
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = cn;
cmd.CommandText = "UPDATE test SET status_id = 1 WHERE test_id = 1";
int numRowsUpdated = cmd.ExecuteNonQuery();
}
catch (MySqlException exSql)
{
Console.Error.WriteLine("Error - SafeMySql: SQL Exception: " + query);
Console.Error.WriteLine(exSql.StackTrace);
}
catch (Exception ex)
{
Console.Error.WriteLine("Error - SafeMySql: Exception: " + query);
Console.Error.WriteLine(ex.StackTrace);
}
}
else
Console.Error.WriteLine("Error - SafeMySql: executeQuery failed. Not connected to DB");
}
Change your try section to the code below:
try
{
using(MySqlConnection cn = new MySqlConnection(connection.ConnectionString))
{
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = cn;
cmd.CommandText = "UPDATE test SET status_id = 1 WHERE test_id = 1";
cn.Open();
int numRowsUpdated = cmd.ExecuteNonQuery();
cmd.Dispose();
}
}
The connection must be opened before you execute a command. In the example above the command object will immediately be disposed and the connection object will implcitly be closed and disposed when you leave the using section.
I don't see the connection being opened.
Here is an example from MSDN: even inside a using block, they open the connection explicitly
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
Edit: The principle is the same for MySQL as it is for SQL Server:
public void CreateMySqlCommand(string myExecuteQuery, MySqlConnection myConnection)
{
MySqlCommand myCommand = new MySqlCommand(myExecuteQuery, myConnection);
myCommand.Connection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}
When I add a Car in my application I get
The ConnectionString property has not been initialized.
I have the problem of ConnectionString property. I check similar question of mine but I found nothing helpfulness.
I use a class connection named dbConnection.cs:
class dbConnection
{
//Connection to database
private string con = "Data Source=(local)\\SQLEXPRESS; Initial Catalog=MLQ7024; Integrated Security=TRUE".ToString();
public string Con
{
get
{
return con;
}
}
}
This is the code of my button
private void btnAddCar_Click(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection(dc.Con))
{
DataTable dtCar = new DataTable();
BindingSource Car_bs = new BindingSource();
using (SqlCommand cmd = new SqlCommand("sp_Add_Car", con))
{
try
{
cmd.CommandType = CommandType.StoredProcedure;
//......
con.Open();
cmd.ExecuteNonQuery();
con.Close();
dtCar.Clear();
da.Fill(dtCar);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\t" + ex.Source);
}
}
}
refreshCar();
}
This is the code of an another button working well without error
private void btnAddPayment_Click(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection(dc.Con))
{
DataTable dtPayment = new DataTable();
using (SqlCommand cmd = new SqlCommand("sp_Add_Paiements", con))
{
try
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#id_paiement", SqlDbType.Char).Value = txtBoxPaymentId.Text;
cmd.Parameters.Add("#montant", SqlDbType.SmallMoney).Value = txtBoxAmount.Text;
cmd.Parameters.Add("#id_Location", SqlDbType.Char).Value = cmbpaymentLesaseId.Text;
//cmd.Parameters.Add("#status", SqlDbType.Char).Value = txtBoxStatusPayment.Text;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
dtPayment.Clear();
da.Fill(dtPayment);
btnAddLease.Hide();
refreshPayments();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\t" + ex.Source);
}
}
}
btnAddPayment.Hide();
}
You aren't showing where you have initialized your dbConnection class. Changing it all to static will probably help, I'm guessing:
static class dbConnection
{
//Connection to database
private static string con = "Data Source=(local)\\SQLEXPRESS; Initial Catalog=MLQ7024; Integrated Security=TRUE"
public static string Con
{
get
{
return con;
}
}
}
If your dbConnection class worked in one method but not the other, chances are you had it initialized in one and not the other. Unless you have to deal with different database connections, using a static class for your database connections is probably the best route.
Then you change your calling method like this:
using (SqlConnection con = new SqlConnection(dbConnection.Con))
{
// blah-blah
}
Assuming dc is your connection, then it has to be initialized with a connection string. Maybe - if it's a class - you have to set some properties, like database path, etc.
SqlConnection Con= New SQLConnection(#"Data Source=(local)\\SQLEXPRESS; Initial Catalog=MLQ7024; Integrated Security=TRUE");