C#: Class/Method That Builds Connection - c#

Completely new to C#.
In my app, several buttons will connection to MySql and pass information to and from it. Each button has it's own connection string, which I find redundant and was curious if there was a way in C# to build a Class or Method, holding the connection string, and call the connection in each button, instead of establishing the connection, then calling it.
I tried building a Public Method which used MySqlConnection mycon parameter and had it return mycon, however, in the other buttons, it saw mycon as a method, not an object. From there I tried a Class (using syntax from dotnetperls and other sites), which have yielded other errors about type. Clearly, being new to this, I am approaching the wrong syntax to build a Class and Method, though I'm assuming that since a Method will be an action, I am actually seeking a class that will hold the objects and allow other parts of the program to access it.
See below pseudo-code as an example:
Current
private void button1_Click(object sender, EventArgs e)
{
MySqlConnection mycon = new MySqlConnection();
mycon.ConnectionString = "Connection";
mycon.Open();
// Code
mycon.Close();
}
private void button2_Click(object sender, EventArgs e)
{
MySqlConnection mycon = new MySqlConnection();
mycon.ConnectionString = "Connection";
mycon.Open();
// Code
mycon.Close();
}
private void button3_Click(object sender, EventArgs e)
{
MySqlConnection mycon = new MySqlConnection();
con.ConnectionString = "Connection";
mycon.Open();
// Code
mycon.Close();
}
Goal:
Some Class
{
//MySqlConnection parameters establish mycon
}
private void button1_Click(object sender, EventArgs e)
{
mycon.Open();
// Code
mycon.Close();
}
private void button2_Click(object sender, EventArgs e)
{
mycon.Open();
// Code
mycon.Close();
}
private void button3_Click(object sender, EventArgs e)
{
mycon.Open();
// Code
mycon.Close();
}
Note: I am aware of the XML approach (and have used it in another one of my programs), but am trying to see if there's a Class/Method approach.

I'd suggest having a method (can probably be static, and exist in a place accessible from anywhere in your code) that deals with all the details of getting a connection, and returns it. Then anywhere you need a connection, call that method.
class SomeClass
{
private void button1_Click(object sender, EventArgs e)
{
using (var conn = Utilities.GetConnection())
{
conn.Open();
// Code
}
}
}
public static class Utilities
{
public static MySqlConnection GetConnection()
{
MySqlConnection conn = new MySqlConnection();
conn.ConnectionString = "Connection";
return conn;
}
}
And use using to ensure that the connection is always closed. It's usually good practice to do this with any IDisposable that you use.
For some info/duscussion on whether Open() should be in GetConnection() or not, see using statement with connection.open

Use a static method to create connection, and using shorthand to close/dispose it:
SomeClass
{
public static MySqlConnection CreateConnection()
{
MySqlConnection mycon = new MySqlConnection();
mycon.ConnectionString = "Connection";
mycon.Open();
return mycon;
}
}
private void button1_Click(object sender, EventArgs e)
{
using (MySqlConnection conn = SomeClass.CreateConnection())
{
}
}

class SomeClass : IDisposable
{
SqlConnection conn;
public SomeClass
{
conn = new SqlConnection("some connectionstring");
}
public void Open()
{
conn.Open()
}
public void Close()
{
conn.Close()
}
public void Dispose()
{
conn.Dispose()
}
}

I would do something like this:
public class DataBase
{
private static string DEFAULT_CONNECTION_STRING = "*your connection string*";
private string connectionString;
private DbProviderFactory factory;
public DataBase()
{
connectionString = DEFAULT_CONNECTION_STRING;
factory = DbProviderFactories.GetFactory("MySql.Data.MySql");
}
public IDataReader GetData(string sql)
{
using(var conn = factory.CreateConnection())
using(var command = factory.CreateCommand())
{
command.CommandText = sql;
command.CommandType = CommandType.Text;
conn.ConnectionString = this.connectionString;
conn.Open();
command.Connection = conn;
return cmd.ExecuteReader();
}
}
}

Related

C# + SQL connection issue

I have a problem with connecting SQL base with c# code. I have done the database and tried to display if my columns are visible, there aren't any problems, warnings, messages in visual studio, but i can't see data from my base. It is very simple database. I used those tutorial to do this connection: https://www.youtube.com/watch?v=p2UeT7dBTEg] But, i have made one database. Here is the SQL connection part of the program:
public partial class MainWindow : Window
{
SqlConnection connection;
string connectionString;
public MainWindow()
{
InitializeComponent();
connectionString = ConfigurationManager.ConnectionStrings["projekt1.Properties.Settings.Database1ConnectionString"].ConnectionString;
}
private void MainWindow_Load(object sender, EventArgs e)
{
DisplayBMI();
}
private void DisplayBMI()
{
using (connection = new SqlConnection(connectionString))
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Table ", connection))
{
DataTable tabelabmi = new DataTable();
adapter.Fill(tabelabmi);
listbmi.DisplayMemberPath = "bmi";
listbmi.SelectedValue = "Id";
listbmi.ItemsSource = tabelabmi.DefaultView;
}
}
Could you try this. I moved DisplayBMI() to MainWindow() constructor.
public partial class MainWindow : Window
{
SqlConnection connection;
string connectionString;
public MainWindow()
{
InitializeComponent();
connectionString = ConfigurationManager.ConnectionStrings["projekt1.Properties.Settings.Database1ConnectionString"].ConnectionString;
DisplayBMI();
}
//private void MainWindow_Load(object sender, EventArgs e)
//{
// DisplayBMI();
//}
private void DisplayBMI()
{
using (connection = new SqlConnection(connectionString))
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Table ", connection))
{
DataTable tabelabmi = new DataTable();
adapter.Fill(tabelabmi);
listbmi.DisplayMemberPath = "bmi";
listbmi.SelectedValuePath = "Id";
listbmi.ItemsSource = tabelabmi.DefaultView;
}
}
}

How to show a form on startup if there is data found in database in C#

What I am trying to do is if for example a user has registered or saved data in the database they will be automatically redirected to a certain form on startup...
Here is the code I've tried so far and it it is not working according to how I want it to be...
In Form1:
// I declared the rowcounts as public
public int rowcounts;
public void Form1_Load(object sender, EventArgs e)
{
SqlConnection connCount = locald.DB.GetSqlConnection();
System.Data.SqlClient.SqlCommand com = new
System.Data.SqlClient.SqlCommand();
com.Connection = connCount;
com.CommandType = CommandType.StoredProcedure;
com.CommandText = #"countval";
rowcounts = Convert.ToInt32(com.ExecuteScalar());
label1.Text = rowcounts.ToString();
}
In Program.cs:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 f1 = new Form1();
if (f1.rowcounts == 0)
{
Application.Run(new Form2()); // if database has no records
}
else
{
Application.Run(new Form1());
}
}
I created a class DB.cs for connection
public class DB
{
public static string ConnectionString
{
get
{
string connStr = ConfigurationManager.ConnectionStrings["locald.Properties.Settings.localdConnectionString"].ToString();
SqlConnectionStringBuilder sb = new SqlConnectionStringBuilder(connStr);
sb.ApplicationName = ApplicationName ?? sb.ApplicationName;
sb.ConnectTimeout = (ConnectionTimeout > 0) ? ConnectionTimeout : sb.ConnectTimeout;
return sb.ToString();
}
}
public static string ApplicationName { get; set; }
public static int ConnectionTimeout { get; set; }
public static SqlConnection GetSqlConnection()
{
SqlConnection cnn = new SqlConnection(ConnectionString);
cnn.Open();
return cnn;
}
}
The problem is even if the database has or without data it would still show the Form1 on startup. What I want is if the database has data it would automatically be redirected to the Form1 and if it has not then it will be in Form2 on startup...
Please help.. Thanks in advance...
defects in your program are,
what is f1 ?
i am seeing that you have coded SQL functions in Form1.cs.
why don't you perform all the SQL operations on program.cs
and redirect to the form as per your query result.
follow as below,
program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
int rowcounts = 0;
SqlConnection connCount = locald.DB.GetSqlConnection();
System.Data.SqlClient.SqlCommand com = new
System.Data.SqlClient.SqlCommand();
com.Connection = connCount;
com.CommandType = CommandType.StoredProcedure;
com.CommandText = #"countval";
rowcounts = Convert.ToInt32(com.ExecuteScalar());
if (rowcounts == 0){
Application.Run(new Form2()); //if database has no records
}
else
{
Application.Run(new Form1());
}
}
Form1.cs
private void Form1_Load()
{
}
I'd post it as a comment, but can't comment with low reputation...
First of all, you're missing "if" in your Program.cs (I believe it's not the real problem, or is it?)
Secondly, you can try to call "Close" on form1 if you don't want it to show, right in its "Initialize", just as an easy solution.
Like that:
private void Form1_Load(object sender, EventArgs e)
{
//...
//Your code
//...
// If no data
this.Close();
}

C# - Change label text from another class

I am a total noob on C# and I'm stuck on changing the status label text from an other class.
When this class connects to db I want to change the label text to "Connected":
public class DBConnect
{
public void Connect()
{
MySqlConnection conn;
string myConnectionString;
myConnectionString = "server = 127.0.0.1; uid=cardb;" +
"pwd=cardb; database=test;";
try
{
Form form = new Form();
conn = new MySqlConnection();
conn.ConnectionString = myConnectionString;
conn.Open();
form.setStatus();
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
}
}
}
This is the method setStatus I created in Form class:
public partial class Form : System.Windows.Forms.Form
{
public Form()
{
InitializeComponent();
}
public void setStatus()
{
StatusTextLabel.Text = "Connected";
}
The label text doesnt change though.. :/
I see no code to create a DBConnect object, or to call its Connect() method, and no code that makes the Form object visible, e.g. form.Show().
Other than that you probably should not create the Form from the Connect method; instead call Connect() from the Form, e.g. in Form_Load(), let it return a status, or better: the conn object (which you are now throwing away after connection), and make Form_Load set the Label.Text based on that.
Example code:
private void Form1_Load(object sender, EventArgs e)
{
var conn = new DBConnect().Connect();
if (conn != null && conn.State == ConnectionState.Open)
{
StatusTextLabel.Text = "Connected";
}
}
public class DBConnect
{
public SqlConnection Connect()
{
SqlConnection conn = ...
// ...
return conn;
}
}
Instead of creating an instance of a new Form, you probably need an instance of already opened form and call the method from there. You can try:
(System.Windows.Forms.Application.OpenForms["Form"] as Form).setStatus();
Pass the form instead of creating a new one.
private Form form {get;set;}
public DBConnect(Form form)
{
this.form = form;
}
Then try this
form.Invoke(new MethodInvoker(() => form.setStatus()));

NullReferenceException was unhandled - what is null?

I'm trying to access an event in my main form by clicking a button (btnsearch_Click) and everytime I clicked it, it says 'object reference not set to an instance of an object'.
Here is my code:
USER CONTROL
namespace Purchase_Order
{
public partial class Search : UserControl
{
public event EventHandler btnSearchClicked;
public Search()
{
InitializeComponent();
}
private void btnsearch_Click(object sender, EventArgs e)
{
btnSearchClicked(sender, e);
}
}
}
MAIN FORM
namespace Purchase_Order
{
public partial class formMain : Form
{
public formMain()
{
InitializeComponent();
}
private void formMain_Load(object sender, EventArgs e)
{
Search searchbox = new Search();
searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}
void SearchClicked(object sender, EventArgs e)
{
MySqlConnection con = new MySqlConnection(serverstring);
try
{
string query = "SELECT * FROM tblclassification WHERE INSTR(class_name, #search)";
MySqlCommand cmd = new MySqlCommand(query, con);
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
Search content = new Search();
cmd.Parameters.AddWithValue("#search", content.btnsearch.Text);
DataTable dt = new DataTable();
da.Fill(dt);
classification control = new classification();
control.dataGridView1.DataSource = dt;
control.dataGridView1.DataMember = dt.TableName;
panelMain.Controls.Clear();
panelMain.Controls.Add(control);
MessageBox.Show("OK");
}
catch (Exception)
{
throw;
}
finally
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
}
You are creating a new instance of your user control in SearchClicked method and you are not registering the event against it.
Search content = new Search();
Also its better if you check whether any control has register your event before raising it like:
private void btnsearch_Click(object sender, EventArgs e)
{
if(btnSearchClicked != null)
btnSearchClicked(sender, e);
}
That means that you haven't got an instance of the type you want to use.
public event EventHandler btnSearchClicked; is just a reference for the "real" object you want to use.
It's like you trying to open a door of a house you only have a blueprint. This isn't really possible (at least not in our universe). You will first need to build the house and then try to enter it. Something like this is the case with your problem.
You will have to read a few tutorials about C#
Edit:
The thing about null is that there is nothing the reference you have is pointing too. If you haven't created anything then there isn't anything to reference...
Because you are trying to use something that doesn't exists (is null) you are getting an exception.
To try and expand a little on Habib's answer (I was going to post this as a comment but it's a little lengthy), you are first creating an instance of Search and registering the event in formMain_Load here:
private void formMain_Load(object sender, EventArgs e)
{
Search searchbox = new Search();
searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}
This is all fine and dandy. However, in SearchClicked, you create a new instance of Search like so:
Search content = new Search();
This is a separate object to the one you created in formMain_Load and you never register the event to this object. It looks like what you want to do is share the Search instance from formMain_Load with the SearchClicked method. To do this, create a property in your codebehind:
public partial class formMain : Form
{
private Search _searchbox;
...
}
Then, in formMain_Load:
private void formMain_Load(object sender, EventArgs e)
{
_searchbox = new Search();
_searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}
Now, you can reuse this object with the event registered in SearchClicked by changing this:
Search content = new Search();
To this:
Search content = _searchbox;
You should find that the exception goes away. Hopefully, this will have provided a little more insight and will help you to understand the cause of the error and how to circumvent it.
Share the Search instance from formMain_Load with the SearchClicked method
MAIN FORM
public partial class formMain : Form
{
private Search _searchbox;
...
private void formMain_Load(object sender, EventArgs e)
{
_searchbox = new Search();
_searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}
void SearchClicked(object sender, EventArgs e)
{
Search content = _searchbox;
MySqlConnection con = new MySqlConnection(serverstring);
try
{
string query = "SELECT * FROM tblclassification WHERE INSTR(class_name, #search)";
MySqlCommand cmd = new MySqlCommand(query, con);
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
cmd.Parameters.AddWithValue("#search", content.btnsearch.Text);
DataTable dt = new DataTable();
da.Fill(dt);
classification control = new classification();
control.dataGridView1.DataSource = dt;
control.dataGridView1.DataMember = dt.TableName;
panelMain.Controls.Clear();
panelMain.Controls.Add(control);
MessageBox.Show("OK");
}
catch (Exception)
{
throw;
}
finally
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
}
}
USER CONTROL
public partial class Search : UserControl
{
public event EventHandler btnSearchClicked;
public Search()
{
InitializeComponent();
}
private void btnsearch_Click(object sender, EventArgs e)
{
btnSearchClicked(sender, e);
}
}

Connecting C# to MySQL and opening connection

This is my simple code just to read something from MySQL. But want I want is to create connection and command when Form is opened and just to open connection when button is clicked and do the rest. But It says:
"The name 'konekcija' does not exist in the current context"
Could someone explain me please.
namespace mysql_windows_console
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void Form1_Load(object sender, EventArgs e)
{
/*========MYSQL KONEKCIJA===========*/
string baza = "server=localhost;database=test;user=root;password=;";
MySqlConnection konekcija = new MySqlConnection(baza);
MySqlCommand comm = konekcija.CreateCommand();
/*========MYSQL KONEKCIJA===========*/
}
private void button1_Click(object sender, EventArgs e)
{
konekcija.Open();
string sql = "SELECT IME,PREZIME FROM tabela";
MySqlDataAdapter adapter = new MySqlDataAdapter(sql,konekcija);
DataTable tab = new DataTable();
adapter.Fill(tab);
dataGridView1.DataSource = tab;
konekcija.Close();
}
}
}
You should declare MySqlConnection outside of the Form_Load EventHandler so you can access it from other methods. Also I would suggest to initialize it in a Form constructor. Since you are using DataAdapter you don't need to use MySqlCommand. Here is the revised code;
namespace mysql_windows_console
{
public partial class Form1 : Form
{
MySqlConnection konekcija;
string baza = "server=localhost;database=test;user=root;password=;"; //so you can access it again if you need it b any chance
public Form1()
{
InitializeComponent();
konekcija = new MySqlConnection(baza);
}
private void button1_Click(object sender, EventArgs e)
{
konekcija.Open();
string sql = "SELECT IME,PREZIME FROM tabela";
MySqlDataAdapter adapter = new MySqlDataAdapter(sql,konekcija);
DataTable tab = new DataTable();
adapter.Fill(tab);
dataGridView1.DataSource = tab;
konekcija.Close();
}
}
}
You're storing konekcija as a local variable. Make it a property like:
private MySqlConnection konekcija { get; set; }
public void Form1_Load(object sender, EventArgs e)
{
//...
this.konekcija = new MySqlConnection(baza);
}
private void button1_click(object sender, EventArgs e)
{
this.konekcija.Open();
//...
}
it simply means that konekcija is not found on the scope of button1_Click.
Minimize the scope of the variable as much as possible. Why not connect only when needed? Example,
const string baza = "server=localhost;database=test;user=root;password=;";
private void button1_Click(object sender, EventArgs e)
{
using (MySqlConnection _conn = new MySqlConnection(baza))
{
using (MySqlCommand _comm = new MySqlCommand())
{
_comm.Connection = _conn;
_comm.CommandText = "SELECT IME,PREZIME FROM tabela";
_comm.CommandType = CommandType.Text;
using (MySqlDataAdapter _adapter = new MySqlDataAdapter(_comm))
{
DataTable _table = new DataTable;
try
{
_adapter.Fill(_table);
dataGridView1.DataSource = _table;
}
catch (MySqlException e)
{
MessageBox.Show(e.Message.ToString());
}
}
}
}
}

Categories

Resources