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();
Related
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!");
}
}
}
}
I've always used Oledb Connection.
but now I need to connect with my Database via Sql connection
yet I don't know how to do so,
can some one provide me an example of a database connected with sql connection?
this code needs a sql connection to be done successfully.
protected void Button1_Click(object sender, EventArgs e)
{
string st = this.TextBox1.Text;
string sqlstr2 = "select * from hsinfo WHERE rname='"+st+ "'";
SqlCommand cmd = new SqlCommand(sqlstr2,);
using (SqlDataReader rd = cmd.ExecuteReader())
{
this.Label1.Text = rd["rmail"].ToString();
}
}
You can check the official Microsoft page for more details SqlConnection Class, but I will reproduce the given example below ...
Aditionally you can check also the Connection String Syntax linked in the previous link.
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();
}
}
This is a simple example code and it's working. This might help you.
Here NextMonth,NextYear,ProcessedDate are auto calculated values comes from another function don't think about that.
String cs = #"Data Source=LENOVO-G510;Initial Catalog=Nelna2;Persist Security Info=True;User ID=sa;Password=123";
protected void Save_Click(object sender, EventArgs e)
{
// SqlConnection con = new SqlConnection(cs);
using (SqlConnection con = new SqlConnection(cs))
{
try
{
SqlCommand command5 = new SqlCommand("insert into MonthEnd (month,year,ProcessedDate) values (#month2,#year2,#ProcessedDate2) ", con);
command5.Parameters.AddWithValue("#month2", NextMonth);
command5.Parameters.AddWithValue("#year2", NextYear);
command5.Parameters.AddWithValue("#ProcessedDate2", ProcessedDate);
command5.ExecuteNonQuery();
}
catch (SqlException ex)
{
Response.Write(ex.Message);
}
}
}
Connection string can be found in DB properties. right click on DB -> properties and Get the Connection String
There is no enougth information to build connection for you, but in the shortes you sth like this:
Server=...;Database=...;User ID=...;Password=...;
For more information just check ConnectionStrings website.
try below code and for more information about c# SQL server connection see this SQL Server Connection
string connetionString = null;
SqlConnection cnn ;
connetionString = "Data Source=ServerName;Initial Catalog=DatabaseName;User ID=UserName;Password=Password"
cnn = new SqlConnection(connetionString);
try
{
cnn.Open();
MessageBox.Show ("Connection Open ! ");
cnn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Can not open connection ! ");
}
I would do something like this:
public static List<Test> GetTests(string testVariable)
{
DataTable result = new DataTable();
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Database"].ConnectionString))
{
connection.Open();
GetQuery(
connection,
QueryGetTests,
ref result,
new List<SqlParameter>()
{
new SqlParameter("#testVariable", testVariable)
}
);
return result.Rows.OfType<DataRow>().Select(DataRowToTest).ToList();
}
}
private static void GetQuery(SqlConnection connection, string query, ref DataTable dataTable, List<SqlParameter> parameters = null)
{
dataTable = new DataTable();
using (SqlCommand command = new SqlCommand(query, connection))
{
command.CommandTimeout = 120;
if (parameters != null)
{
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
}
using (SqlDataAdapter reader = new SqlDataAdapter(command))
{
reader.Fill(dataTable);
}
}
}
I think this can help you.
string sqlString = "select * from hsinfo WHERE rname=#st";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DatabaseName"].ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
{
cmd.Parameters.Add("#st", st);
using (SqlDataReader rd = cmd.ExecuteReader())
{
if (rd.Read())
{
this.Label1.Text = rd["rmail"].ToString();
}
}
}
}
Trick:
Create a file with .udl Extension on your Desktop
Run it by Double click
Compile form by Choosing provider, username, password, etc...
Test connection and save
Close the form
Open now the .udl file with Notepad
You will see the connection string that you can use with ADO.NET
I'm coding a Windows Forms login page for an administration application. My problem is, that when I try to log on, I get the error message
System.InvalidOperationException: 'The connection is already open.'
Any help would be appreciated
public partial class Form1 : Form
{
MySqlConnection con = new MySqlConnection (#"Database= app2000; Data Source = localhost; User = root; Password =''");
int i;
public Form1()
{
InitializeComponent();
}
private void btnClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnLogin_Click(object sender, EventArgs e)
{
i = 0;
con.Open();
MySqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM adminlogin WHERE username='" + txtBoxUsername + "'AND password='" + txtBoxPassword + "'";
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
i = Convert.ToInt32(dt.Rows.Count.ToString());
if (i == 0)
{
lblerrorInput.Show();
}
else
{
this.Hide();
Main ss = new Main();
ss.Show();
}
}
}
Do not cache Connection, it's a typical antipattern, but recreate it when you need it
public partial class Form1 : Form {
...
//DONE: Extract method
private static bool UserExists(string userName, string password) {
//DONE: Do not cache connections, but recreate them
using (MySqlConnection con = new MySqlConnection (#"...") {
con.Open();
//DONE: wrap IDisposable into using
using (MySqlCommand cmd = con.CreateCommand()) {
cmd.CommandType = CommandType.Text;
//DONE: Make query being readable
//DONE: Make query being parametrized
cmd.CommandText =
#"SELECT *
FROM adminlogin
WHERE username = #UserName
AND password = #PassWord"; // <- A-A-A! Password as a plain text!
//TODO: the simplest, but not the best solution:
// better to create parameters explicitly
// cmd.Parameters.Add(...)
cmd.Parameters.AddWithValue("#UserName", txtBoxUsername);
cmd.Parameters.AddWithValue("#PassWord", txtBoxPassword);
// If we have at least one record, the user exists
using (var reader = cmd.ExecuteReader()) {
return (reader.Read());
}
}
}
}
Finally
private void btnLogin_Click(object sender, EventArgs e) {
if (!UserExists(txtBoxUsername.Text, txtBoxPassword.Text))
lblerrorInput.Show();
else {
Hide();
Main ss = new Main();
ss.Show();
}
}
You forgot to close the connection, use con.Close() at the end to close the connection and avoid this error the next time the event fires.
There are some mistakes in your code.
You should close the sql connection when you finished your process.
I suggest you to use using statement to dispose connection instance after complete database actions.
Also, you should use command parameters to prevent Sql injection.
You can declare connection string like this;
private string _connectionString = #"Database= app2000; Data Source = localhost; User = root; Password =''";
The method part looks like;
using (var con = new MySqlConnection(_connectionString))
{
i = 0;
con.Open();
MySqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM adminlogin WHERE username = #username and password = #password";
cmd.Parameters.AddWithValue("#username", txtBoxUsername);
cmd.Parameters.AddWithValue("#password", txtBoxPassword);
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
i = Convert.ToInt32(dt.Rows.Count.ToString());
if (i == 0)
{
lblerrorInput.Show();
}
else
{
this.Hide();
Main ss = new Main();
ss.Show();
}
con.Close();
}
First, don't cache your Connection objects. It's a terrible practice and I've had to go back and fix it every time I accept a new job and inherit code. Most database access classes implement IDisposable, so use using and take advantage of it to keep your code clean. FYI, Readers and Adapters are also IDisposable so you can do the same with them, too.
string command = "select stuff from mydata";
string connection = GetConnectionStringFromEncryptedConfigFile();
using (var conn = new SqlConnection(connection))
{
using (var cmd = new SqlCommand(command, conn))
{
cmd.Connection.Open();
//do stuff
}
}
Second, if you're forced to use a cached connection (i.e., you inherited horrible code and don't have time to fix it yet), check your State first.
if(conn.State != System.Data.ConnectionState.Open)
{
conn.Open();
}
Note that there are a lot more states than just Open and Closed, and if you try to open a connection that is busy, you'll still get errors. It's still a much wiser approach to use the IDisposable implementations with using so you don't have to worry about this sort of thing so much.
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();
}
I'm having this little issue : each time my code executes the InsertOrder() routine below, i get this exception message : "connection string has not been initiated".
Here's the code of InsertOrder() method:
private void InsertOrder()
{
string insertSQL = "";
insertSQL += "INSERT INTO Orders (";
insertSQL += "UserName, DateCreated, LastUpdate, Description, PaymentType, Delivery, Total) ";
insertSQL += "VALUES (#UserName, #DateCreated, #LastUpdate, #Description, #PaymentType, #Delivery, #Total)";
SqlCommand cmd0 = new SqlCommand(insertSQL, connection);
// Adds the parameters
cmd0.Parameters.AddWithValue("#UserName", Profile.UserName.ToString());
cmd0.Parameters.AddWithValue("#DateCreated", Profile.Orders.SCart.DateCreated());
cmd0.Parameters.AddWithValue("#LastUpdate", Profile.Orders.SCart.LastUpdate());
cmd0.Parameters.AddWithValue("#Description", Profile.Orders.SCart.GetCartDescription());
cmd0.Parameters.Add("#PaymentType", SqlDbType.Bit).Value = Profile.Orders.SCart.PaymentType;
cmd0.Parameters.Add("#Delivery", SqlDbType.Bit).Value = Profile.Orders.SCart.Delivery;
cmd0.Parameters.AddWithValue("#Total", Profile.Orders.SCart.Total);
try
{
using (connection)
{
connection.Open();
cmd0.ExecuteNonQuery();
}
string selectSQL = "SELECT OrderID FROM Orders WHERE UserName=#UserName AND DateCreated=#DateCreated";
SqlCommand cmd1 = new SqlCommand(selectSQL, connection);
cmd1.Parameters.AddWithValue("#UserName", Profile.UserName);
cmd1.Parameters.AddWithValue("#DateCreated", Profile.Orders.SCart.DateCreated());
SqlDataReader reader;
using (connection)
{
connection.Open();
reader = cmd1.ExecuteReader();
reader.Read();
OrderID = (int)reader["OrderID"];
reader.Close();
}
// Store registered customer information for later usage..
if (!Profile.IsAnonymous)
{
string insertSQL2 = "";
insertSQL2 += "INSERT INTO CategoriesInAnOrder (";
insertSQL2 += "OrderID, CategoryID, Quantity) VALUES (#OrderID, #CategoryID, #Quantity)";
foreach (CartItem item in Profile.Orders.SCart.Items)
{
SqlCommand cmd2 = new SqlCommand(insertSQL2, connection);
cmd2.Parameters.AddWithValue("#OrderID", OrderID);
cmd2.Parameters.AddWithValue("#CategoryID", item.CategoryID);
cmd2.Parameters.AddWithValue("#Quantity", item.Quantity);
using (connection)
{
connection.Open();
cmd2.ExecuteNonQuery();
}
}
}
}
catch (Exception err)
{
pnlWizard.Visible = false;
lblError.Text = err.Message;
}
}
Probabily it's worth saying i have placed a SqlConnection object inside my SuperClass, so every child class (like the one which contains the above method) inherits this attribute.
The shared SqlConnection object is set as follows:
protected SqlConnection connection = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["DefaultConnectionString"].ConnectionString);
Sorry for my english... i'm italian
I think the
using(connection)
may be the source of your problem.
The using() is going to cause Dispose() to be called on the connection when the call has completed, but your connection is only being instantiated once.
Next time you come to use it, it's not going to be in a healthy state!
Consider creating a new connection each time:
protected SqlConnection connection
{
get
{
return new SqlConnection
(System.Web.Configuration.WebConfigurationManager.ConnectionStrings
["DefaultConnectionString"].ConnectionString);
}
}
I suspect the problem is that you are using the value from a field. That will work once, but after the Dispose() you have doomed that connection.
For this scenario, I use a custom EnsureOpen() method that returns an IDisposable if it wasn't already open; usage:
using(connection.EnsureOpen())
{
// use it
}
This way the connection isn't disposed prematurely but is open when needed. Plus it works whether it was already open or not.
I can share EnsureOpen later if you want.