Display DateTime iin C# and WPF - c#

I have a DateTime variable selected in a 1st window and I'm trying to display in in a 2nd window. It connects to the DB as it should be,but it appears a random data from the DB,not the selected one.
Here is the code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Are you sure?");
Window1 win1 = new Window1();
win1.Show();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
{
string connectionString = null;
SqlConnection cnn;
connectionString =
#"Data Source=IBWS05\MSSQLSERVER2012;Initial Catalog=Interview;Integrated Security=True";
try
{
SqlConnection con =
new SqlConnection(
#"Data Source=IBWS05\MSSQLSERVER2012;Initial Catalog=Interview;Integrated Security=True");
SqlCommand cmd = new SqlCommand();
con.Open();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText =
"insert into [Event] (Description,StartData,EndData,Type) values (#description,#startdata,#endata,#type)";
cmd.Parameters.AddWithValue("description", descriptionTxt.Text);
cmd.Parameters.AddWithValue("startData", StartDate.Value);
cmd.Parameters.AddWithValue("endata", EndDate.Value);
cmd.Parameters.AddWithValue("type", typeTxt.Text);
cmd.ExecuteNonQuery();
con.Close();
MessageBox.Show("Data Saved");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
////Window2 win = new Window2(id);
//Window2 win3 = new Window2();
//this.Close();
//win3.Show();
SqlConnection conn =
new SqlConnection(
#"Data Source=IBWS05\MSSQLSERVER2012;Initial Catalog=Interview;Integrated Security=True");
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
comm.CommandType = CommandType.Text;
int query= Convert.ToInt32(comm.CommandText = "select MAX(StartData) from [Events]");
Window2 win = new Window2(query);
win.Show();
}
The error is input string was not in a correct format. How can I convert it?

There are a few things you need to look at/consider in your code, first is your issue.
This line of code:
int query= Convert.ToDateTime(comm.CommandText = "select MAX(DateTime) from [Events]");
Won't achieve what you are after as you aren't executing the code. You are actually trying to convert your command object to a Date Time.
Earlier in your method you are writing to the database and part of that you call the following:
cmd.ExecuteNonQuery();
There are various other methods that you have on the command object that all work in different ways. To read about them visit this MSDN page, but essentially you probably want to use the ExectuteScalar method for what you are trying to do.
Next, I would consider moving your connection string to the app.config file and accessing it from there rather than typing it out multiple times.
And finally, I would use a using statement for each of your Connection's so that you ensure they are being disposed of correctly.
Just some extra food for thought.

Related

Creating a Data Reader from a C# Object

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!");
}
}
}
}

c# System.InvalidOperationException: 'The connection is already open.'

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.

oledb connection string not initialized

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
}
}

C# MDI can't populate listbox on child form

I am trying to populate a listbox in C# from a table in sql server. The table is set up as:
tblTables
TableID int
SeatingCapacity int
CurrentCapacity int
The code I am trying to use is:
private void fillListBox()
{
String connectionString = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(connectionString);
SqlDataAdapter da = new SqlDataAdapter();
String commandString = "SELECT TableID, SeatingCapacity, CurrentCapacity from tblTables";
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;
conn.Open();
cmd.CommandText = commandString;
cmd.Connection = conn;
dr = cmd.ExecuteReader();
lstTableList.Items.Clear();
lstTableList.BeginUpdate();
while (dr.Read())
{
lstTableList.Items.Add(dr.GetInt32(0) + " - " + dr.GetInt32(1) + " - " + dr.GetInt32(2));
}
lstTableList.EndUpdate();
dr.Close();
conn.Close();
}
And the code for the parent form to transfer is:
private void mnuFormsTables_Click(object sender, EventArgs e)
{
frmTables aTables = new frmTables();
aTables.MdiParent = this;
aTables.Show();
aTables.Focus();
}
I call fillListBox() is the form load of frmTables. However when I put a break point on
String connectionString = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
It shows that right after that line the code jumps to the parent form at
aTables.Show();
Any help would be greatly appreciated. I am also not sure if that is the proper way to populate the listbox either. Preferably it would be nice if the listbox could show the table ID and add "Full" beside it if the current capacity >= seating capacity.
The github repo URL for this is https://github.com/resistince/StaufferRestaurant
EDIT: If I use:
String connectionString = Properties.Settings.Default.StaufferRestaurantConnectionString;
instead of using the ConfigurationManager it works. I have System.Configuration.dll as a reference and the proper using statement so I don't know why it doesn't work right.

Inserting data multiple times into an SQL table, from a single button on Windows Forms

I am inserting data from a Windows Forms form into an SQL database as below:
public partial class Form1 : Form
{
SqlConnection c = new SqlConnection();
string q = "Trusted_Connection = true; ";
public Form1()
{
InitializeComponent(); c.ConnectionString = q;
MessageBox.Show("Connecting Database");
}
private void button1_Click(object sender, EventArgs e)
{
string w = "insert into checkmultiuser(username) values (#username)";
SqlCommand cmd = new SqlCommand(w, c);
cmd.Parameters.Add("#username", SqlDbType.VarChar);
cmd.Parameters["#username"].Value = textBox1.Text;
cmd.ExecuteReader();
}
But, when I click the button again, then it says "There is already an open DataReader associated with this Command which must be closed first.".
How do I deal with it?
*UPDATE: * I have changed the button click event code as below:
private void button1_Click(object sender, EventArgs e)
{
**c.Open();**
string w = "insert into checkmultiuser(username) values (#username)";
SqlCommand cmd = new SqlCommand(w, c);
cmd.Parameters.Add("#username", SqlDbType.VarChar);
cmd.Parameters["#username"].Value = textBox1.Text;
//cmd.ExecuteNonQuery();
cmd.ExecuteReader();
**c.Close();**
}
What are its drawbacks? One would be that again and again the connection is opened and closed when the button is clicked.
A reader needs an open connection because you retrieve the results one at a time. You'll want to do an ExecuteNonQuery() for inserts, deletes and updates. You also need to close your connection afterwards. The alternative is to wrap your inserts into a loop if you plan to do multiple inserts.
There are a couple of ways you can do this. This way is useful if you plan to reuse the same connection object and command object over and over again:
public partial class Form1 : Form
{
SqlConnection _cn;
SqlCommand _cmd;
const string ConnString = "Enter your connection string here";
readonly string _insertQuery;
const string UsernameParm = "#username";
public Form1()
{
InitializeComponent();
_cn = new SqlConnection(ConnString);
_cmd = new SqlCommand(InsertQuery, _cn);
_cmd.Parameters.Add(UsernameParm, SqlDbType.VarChar);
_insertQuery = String.Format("INSERT INTO checkmultiuser(username) VALUES ({0})",
UsernameParm);
}
private void button1_Click(object sender, EventArgs e)
{
_cmd.Parameters[UsernameParm].Value = textBox1.Text;
try
{
_cn.Open();
_cmd.ExecuteNonQuery();
}
catch (Exception ex) // probably best to catch specific exceptions
{
// handle it
}
finally
{
_cn.Close();
}
}
}
Just be sure to dispose of the connection and command objects (when the form closes or where ever makes the most sense for your application).
Using blocks are a safer alternative, but they will dispose of the object each time (although connections use connection pooling by default):
public partial class Form1 : Form
{
const string ConnString = "Enter your connection string here";
readonly string _insertQuery;
const string UsernameParm = "#username";
public Form1()
{
InitializeComponent();
_insertQuery = String.Format("INSERT INTO checkmultiuser(username) VALUES ({0})",
UsernameParm);
}
private void button1_Click(object sender, EventArgs e)
{
using (var cn = new SqlConnection(ConnString))
{
using (var cmd = new SqlCommand(InsertQuery, cn))
{
cmd.Parameters.Add(UsernameParm, SqlDbType.VarChar);
cmd.Parameters[UsernameParm].Value = textBox1.Text;
cn.Open();
cmd.ExecuteNonQuery();
}
}
}
}
Any combination will work as well. You could setup the connection once and just wrap the command object in a using block. I know some people are not fans of nested using blocks (since behind the scenes it is try(try finally) finally)).
What Jason said.
Whilst you're there it might be worth perhaps changing your code slightly to:
private void button1_Click(object sender, EventArgs e)
{
string w = "insert into checkmultiuser(username) values (#username)";
c.Open();
using (SqlCommand cmd = new SqlCommand(w, c))
{
cmd.Parameters.Add("#username", SqlDbType.VarChar);
cmd.Parameters["#username"].Value = textBox1.Text;
cmd.ExecuteNonQuery();
}
}
to ensure the objects are correctly disposed of.
Could perhaps put it in a try{} block too, and close your connection in the finally{ c.Close();}
First of all, you should use ExecuteNonQuery to handle INSERTS, UPDATES and DELETE. ExecuteNonQuery is used when you are not expecting a value back from the database.
But if you actually want to use a DataReader in another situation, you should use it like shown below.
using (SqlDataReader reader= cmd.ExecuteReader())
{
while (reader.Read())
{
//Do the reading
}
}
This ensures that the SqlDataReader gets closed, once the intended job is done.
Another potential fix it to set MARS (Multiple Active Result Sets) to true in your connection string.
You can try :
cmd.ExecuteReader(CommandBehavior.CloseConnection);

Categories

Resources