I want to access the openConnection from my dbconnect class from by other form but it does not work properly. I have to copy-paste the entire Oopenconnection to the other page for them to access it.
class dbconnect
class DB_Connect
{
private MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
//Constructor
public DB_Connect()
{
Initialize();
}
//Initialize values
private void Initialize()
{
server = "localhost";
database = "xyz";
uid = "root";
password = "";
string connectionString = $"datasource=127.0.0.1;port = 3306; SERVER={server}; DATABASE={database}; USERNAME={uid}; PASSWORD={password};sslmode=none";
connection = new MySqlConnection(connectionString);
}
//open connection to database
public bool OpenConnection()
{
try
{
connection.Open();
return true;
}
catch (MySqlException ex)
{
switch (ex.Number)
{
case 0:
MessageBox.Show("Cannot connect to server. Contact administrator");
break;
case 1045:
MessageBox.Show("Invalid username/password, please try again");
break;
}
return false;
}
}
//Close connection
public bool CloseConnection()
{
try
{
connection.Close();
return true;
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
}
MyForm 2
On click data is being displayed on dataGridView
private void display_record_Click(object sender, EventArgs e)
{
DB_Connect connect = new DB_Connect(); // I believe this part does not work
string show_query = "SELECT * FROM testing_tb";
if (connect.OpenConnection() == true)
{
using (MySqlCommand cmd_DB = new MySqlCommand(show_query, connection))
{
try
{
using (MySqlDataReader reader = cmd_DB.ExecuteReader())
if (reader.HasRows)
{
dt = new DataTable();
dt.Load(reader);
dataGridView1.DataSource = dt;
}
else
{
MessageBox.Show("No data record detected");
}
connect.CloseConnection();
}
catch (Exception ex)
{
MessageBox.Show("Could not connect to database!\n" + ex, "Database Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}// end of catch
} // end of MySQLCommand
} // end of connection check
}
I want to access data from my dtconnect class so that I do not have to paste public bool OpenConnection(){} in every new form that I want to open connection.
Error: could not connect to database, connection must be valid and open, etc..
If you really want the connection available everywhere you can use this:
public static class Connection
{
private const string ConnectionString = "YOUR CONNECTION";
public static System.Data.SqlClient.SqlConnection Conn { get; private set; } = null;
public static void Open()
{
try
{
Conn = new System.Data.SqlClient.SqlConnection(ConnectionString);
Conn.Open();
}
catch { System.Windows.MessageBox.Show("Can't connect to the server, please check if you have an internet connection."); }
}
public static void Close() { Conn.Close(); }
}
It is not recommended because your connection will be open at all time so you should do this instead:
public static class Connection
{
private const string ConnectionString = "YOUR CONNECTION";
public static System.Data.SqlClient.SqlConnection Conn { get; private set; } = null;
public static void Create() { Conn = new System.Data.SqlClient.SqlConnection(ConnectionString); }
public static void Open()
{
try { Conn.Open(); }
catch { System.Windows.MessageBox.Show("Can't connect to the server, please check if you have an internet connection."); }
}
public static void Close() { Conn.Close(); }
}
And you open and close your connection when needed.
So basically, when you open your connection when using a query you use Connection.Open() and Connection.Close(). It is now accessible from everywhere if the class is in the using of your forms.
Here's a link about the connection state: https://softwareengineering.stackexchange.com/questions/142065/creating-database-connections-do-it-once-or-for-each-query
Related
I'm learning database connectivity using C# Windows Form Application in Visual Studio and SQL Server Management Studio.
The problem I'm having is I'm unable to access the AddParams() and sqlQueryCmd() functions from the SQLConn.cs Class.
I've tried changing the access modifiers from private to public but it didn't work. Can anyone guide me here? I don't know what I'm doing wrong.
SQLConn.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using Microsoft.Data.SqlClient;
namespace dbConnectivityTest1
{
public class SQLConn
{
public static void Main1(string[] args)
{
using (SqlConnection connString = new SqlConnection("Server=ServerName;Database=DatabaseName;User Id=UserID;\r\nPassword=Password;"))
{
List<SqlParameter> paramList = new List<SqlParameter>();
string AddParams(string tableName, object insVal)
{
SqlParameter sqlparams = new SqlParameter(tableName, insVal);
paramList.Add(sqlparams);
}
SqlCommand sqlCmd = new SqlCommand();
string sqlQueryCmd(string sqlQuery)
{
int recordCount = 0;
string excptnShow = "";
try
{
connString.Open();
SqlCommand sqlCmd = new SqlCommand(sqlQuery, connString);
paramList.ForEach(p => { sqlCmd.Parameters.Add(p); });
paramList.Clear();
DataTable sqlDT = new DataTable();
SqlDataAdapter sqlDA = new SqlDataAdapter(sqlCmd);
recordCount = sqlDA.Fill(sqlDT);
}
catch(Exception ex)
{
excptnShow = "Error: \r\n" + ex.Message;
}
finally
{
if (connString.State == ConnectionState.Open)
{
connString.Close();
}
}
}
}
}
}
}
Form1.cs
namespace dbConnectivityTest1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private SQLConn sqlDB = new SQLConn();
private void enterNametextBox_Click(object sender, EventArgs e)
{
enterNametextBox.Clear();
}
private void submitButton_Click(object sender, EventArgs e)
{
while(fullNameTextBox.Text.Length <= 0)
{
MessageBox.Show("Please enter your Full Name!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
while(contactTextBox.Text.Length <= 0)
{
MessageBox.Show("Please enter your Contact Number!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
while(ageTextBox.Text.Length <= 0)
{
MessageBox.Show("Please enter your Age!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
while(emailTextBox.Text.Length <= 0)
{
MessageBox.Show("Please enter your E-mail!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
System.Text.RegularExpressions.Regex emailRegex = new System.Text.RegularExpressions.Regex(#"^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+$");
while(!emailRegex.IsMatch(emailTextBox.Text))
{
MessageBox.Show("Please enter a valid E-mail!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
InsVal();
}
public void InsVal()
{
**I am trying to call the SQLConn.cs Functions here**
}
}
}
Movint addParam method/function would not solve the problem since the SqlParam variable is not available in sqlConn class.
the better approach for your goal is to to this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace dbConnectivityTest1
{
public class SQLConn
{
private readonly string _connectionString;
private List<SqlParameter> _paramList;
public SQLConn()
{
_connectionString="Server=ServerName;Database=DatabaseName;User Id=UserID;\r\nPassword=Password;";
_paramList = new List<SqlParameter>();
}
public void AddParams(string tableName, object insVal)
{
SqlParameter sqlparams = new SqlParameter(tableName, insVal);
_paramList.Add(sqlparams);
}
public void sqlQueryCmd(string sqlQuery)
{
using (var sqlConn = new SqlConnection(_connectionString))
{
int recordCount = 0;
string excptnShow = "";
try
{
sqlConn.Open();
SqlCommand sqlCmd = new SqlCommand(sqlQuery, sqlConn);
_paramList.ForEach(p => { sqlCmd.Parameters.Add(p); });
_paramList.Clear();
DataTable sqlDT = new DataTable();
SqlDataAdapter sqlDA = new SqlDataAdapter(sqlCmd);
recordCount = sqlDA.Fill(sqlDT);
}
catch (Exception ex)
{
excptnShow = "Error: \r\n" + ex.Message;
}
finally
{
if (sqlConn.State == ConnectionState.Open)
{
sqlConn.Close();
}
}
}
}
}
}
in this scenario there is no need for Main method since every application can have only one Main method and winForms by default already have one Main method.
secondly, the SQLConn class can have private field of type List,
and a public method called AddParam which its responsibility is to add new params to it.
Lastly, a public SqlQueryCmd method is added to do the rest of the job.
you can now use this class to execute your query like this:
private void button1_Click(object sender, EventArgs e)
{
var sqlConn = new SQLConn();
sqlConn.AddParams("tableName","your Object");
sqlConn.AddParams("tableName","your Object");
sqlConn.AddParams("tableName","your Object");
sqlConn.sqlQueryCmd("Query");
}
I've got four main files in play here: Form 1, which is called frmLogin, Form2, which is called frmUserHome, a class called DbConnector.cs and a class called BankAccount.cs
The program works as follows: Form1 calls method from DBConnector -> DB Connector method fills an object and it's variables which is instantiated in DBConnector. This object is of class BankAccount.cs
Then, after the method finishes and if successful, Form1 instantiates Form2 and it opens. In form2 is where I want to access the object that was created in the DBconnector class. How do I do this? I've tried instantiating new objects of BankAccount.cs in there, I've tried all these different constructor stuff I've seen on here. Nothing seems to be working.
For reference: the object is populated when it runs in Dbconnector. However, when I try to receive data when I use it in Form2, all of the fields are NULL.
I've made countless adjustments from reading different posts on here so the code is rightfully a mess now and probably extremely unorganised.
Here's the main portions of my code below:
Form1
namespace BankingSystem
{
public partial class frmLogIn : Form
{
public BankAccount myBankAccount = new BankAccount();
dbConnector newConnector;
public frmLogIn()
{
InitializeComponent();
timerMain.Enabled = true;
timerMain.Start();
}
private void btnLogIn_Click(object sender, EventArgs e)
{
try
{
newConnector.CheckDetailsLogin(accountNumTextBox.Text, pinNumTextBox.Text);
frmUserHome UserHome = new frmUserHome();
MessageBox.Show("Success! Happy Banking!");
UserHome.ShowDialog();
}
catch
{
MessageBox.Show("Failed - incorrect login details.");
}
}
}
}
DBConnector Class:
namespace BankingSystem
{
public class dbConnector
{
Boolean isCorrect = false;
private static SQLiteConnection sqlconnConnection;
public BankAccount myBankAccount = new BankAccount();
public DataSet myAppDataSet = new DataSet(); // created for you to use and push data into
public dbConnector(string strFilePath)
{
try
{
sqlconnConnection = new SQLiteConnection("Data Source=" + strFilePath);
}
catch (Exception ex)
{
throw new Exception("DbConnector initialisation unsuccessful:\n" + ex.Message);
}
}
public void CheckDetailsLogin(string strAccno, string strPin)
{
// this is where check ou the boiler plate code and adjst to my APP.
try
{
DataTable dtUser = new DataTable();
sqlconnConnection.Open();
string strQuery2 = #"SELECT * FROM Accounts WHERE Account_Number='"+ strAccno +"' AND PIN='"+ strPin +"';"; // example of a parametrised SQL statement.
SQLiteCommand sqlcomCommand2 = new SQLiteCommand(strQuery2, sqlconnConnection);
SQLiteDataAdapter sqldatadptAdapter = new SQLiteDataAdapter(sqlcomCommand2); // local SQL data Adaptor
try
{
sqldatadptAdapter.Fill(dtUser);
}
catch (Exception ex)
{
// Exception will the "thrown"/Raised when there was a problem
throw new Exception($"SELECT unsuccessful:\n{ex.Message}");
}
finally
{
sqlconnConnection.Close();
}
if (dtUser.Rows.Count == 0)
{
// the record set comes back with no records found, an empty Datatable with no rows
// means there was no data matching your query
throw new Exception("No Such Bank user found");
}
else
{
// change to your applications needs
// Rows[0] - we are expecting at least 1 row, and its basically an array so we address
// the first element with 0
// Rows[0]["fieldnamefromDB"] <- referencing the column in the DB
//this.strID = strUserID;
myBankAccount.AccountNumber = dtUser.Rows[0]["Account_Number"].ToString();
myBankAccount.AccountPin = dtUser.Rows[0]["PIN"].ToString();
myBankAccount.AccountBalance = Convert.ToDecimal(dtUser.Rows[0]["Balance"]);
myBankAccount.AccountHolder = dtUser.Rows[0]["First_Name"].ToString();
myBankAccount.AccountAddress = dtUser.Rows[0]["Home_Address"].ToString();
myBankAccount.MyAccountGUID = dtUser.Rows[0]["GUID"].ToString();
if (myBankAccount.AccountNumber == strAccno && myBankAccount.AccountPin == strPin)
{
isCorrect = true;
}
else
{
isCorrect = false;
}
//myLocalBankAccUsr
}
}
catch (Exception ex)
{
// exception thrown for the whole method or function
throw new Exception($"User(string):\n{ex.Message}");
}
}
BankAccount.cs class
namespace BankingSystem
{
public class BankAccount
{
private string accountNumber;
private decimal accountBalance;
private string accountHolder;
private string accountPhoneNumber;
private string accountAddress;
private string accountPin;
private string myAccountGUID;
// private string AccountHolderGUID;
// private string AccountTypeGUID;
public string AccountNumber
{
get { return accountNumber; }
set { accountNumber = value; }
}
public decimal AccountBalance
{
get { return accountBalance; }
set { accountBalance = value; }
}
public string AccountHolder
{
get { return accountHolder; }
set { accountHolder = value; }
}
public string AccountPhoneNumber
{
get { return accountPhoneNumber; }
set { accountPhoneNumber = value; }
}
public string AccountAddress
{
get { return accountAddress; }
set { accountAddress = value; }
}
public string AccountPin
{
get { return accountPin; }
set { accountPin = value; }
}
public string MyAccountGUID
{
get { return myAccountGUID; }
set { myAccountGUID = value; }
}
public Boolean CanWithDrawAmount(decimal AmountToTransfer)
{
if (AmountToTransfer > this.AccountBalance){
return false;
}else
{
return true;
}
}
public void UpdatePIN()
{
// connect to bank DB connector
// send it the new pin
// SQL update command
}
}
}
Here is Form2:
namespace BankingSystem
{
public partial class frmUserHome : Form
{
public frmUserHome()
{
InitializeComponent();
tabMainForm.Appearance = TabAppearance.FlatButtons;
tabMainForm.ItemSize = new Size(0, 1);
tabMainForm.SizeMode = TabSizeMode.Fixed;
timerMain.Enabled = true;
timerMain.Start();
}
private void frmUserHome_Load(object sender, EventArgs e)
{
labelWelcome.Text = "Welcome "; //newMainBank.AccountHolder;
}
The 'labelWelcome.Text = "Welcome" is where I want the name stored inside the object to be used. So it should ideally access the BankAccount class, access the AccountHolder field and use that field to concat onto the end of the 'Welcome' text. However, it just shows 'Welcome' and no name on the end, when I run the program (because all values get reset to null in form2.. for some reason)
Below I have updated the code for Form1 and Form2.
Form 1
namespace BankingSystem
{
public partial class frmLogIn : Form
{
dbConnector newConnector;
public frmLogIn()
{
InitializeComponent();
newConnector = new dbConnector(**pass str file path**);
timerMain.Enabled = true;
timerMain.Start();
}
private void btnLogIn_Click(object sender, EventArgs e)
{
try
{
newConnector.CheckDetailsLogin(accountNumTextBox.Text, pinNumTextBox.Text);
frmUserHome UserHome = new frmUserHome(newConnector.myBankAccount);
MessageBox.Show("Success! Happy Banking!");
UserHome.ShowDialog();
}
catch
{
MessageBox.Show("Failed - incorrect login details.");
}
}
}
}
Form 2
namespace BankingSystem
{
public partial class frmUserHome : Form
{ public BankAccount _bankAccount;
public frmUserHome(BankAccount bankAccount)
{
InitializeComponent(); _bankAccount = bankAccount;
tabMainForm.Appearance = TabAppearance.FlatButtons;
tabMainForm.ItemSize = new Size(0, 1);
tabMainForm.SizeMode = TabSizeMode.Fixed;
timerMain.Enabled = true;
timerMain.Start();
}
private void frmUserHome_Load(object sender, EventArgs e)
{
labelWelcome.Text = "Welcome "+ bankAccount.AccountHolder;
}
I would appreciate some help with async/Task implementation in my Windows Form application.
In this app, I retrieve data from the datacenter SQl server database using WCF services, so part of this code runs on the client and some on the datacenter server where it retrieves the data and returns it. I’d like to optimize the code using async/Task on the clien or server or preferably both. The example code starts with a Windows Form with a button, when the button is clicked it gets a value from the database, displays it and updates a local variable.
I’m not clear if I can simply implement async/Task and Task.Run in the first button click event or whether the code should be cascaded through all methods, or something in between. I'm also not clear on how to handle the wcf service.
I’ve created a simplified example of the code, pretty close to sequentially.
In this code, the return value updates the windows form. I’d like to see how this code is optimized using async/Task await for this purpose and what would be different if the code did not return a value.
public partial class Form1 : Form
{
int returnvalue = 0;
public Form1()
{
InitializeComponent();
}
private void btnGetResult_Click(object sender, EventArgs e)
{
int rowcount = ChangeProductPrice(.05m);
txtResult.Text = rowcount.ToString();
}
private int ChangeProductPrice(decimal priceincrease)
{
int rv = MyData.WebServiceObject.ChangePrice(priceincrease);
UpdateLocalVariables(rv);
return rv;
}
private void UpdateLocalVariables(int rv)
{
returnvalue = rv;
}
}
public static class MyData
{
private static IMyDataWCFService _webserviceobject = null;
public static IMyDataWCFService WebServiceObject
{
get
{
if (_webserviceobject is null)
{
//...code to initialize it
}
return _webserviceobject;
}
}
}
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IMyDataWCFService
{
[OperationContract]
int ChangePrice(decimal priceincrease);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyDataWCFService : IMyDataWCFService
{
private MyDataService _serviceObject = null;
private MyDataService ServiceObject
{
get
{
if (_serviceObject == null)
{
_serviceObject = new MyDataService();
}
return _serviceObject;
}
}
public int ChangePrice(decimal priceincrease)
{
return ServiceObject.ChangePrice(priceincrease);
}
}
public class MyDataService //running on server
{
public int ChangePrice(decimal priceincrease)
{
int rows = 0;
SqlConnection conn = null;
try
{
conn = this.GetSqlConnection();
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
cmd.CommandText = "mysp_UpdatePrice";
cmd.Parameters.Add(new SqlParameter("#Rate", priceincrease));
conn.Open();
rows = cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
ProcessError(ex);
}
finally
{
if (conn != null)
ReturnSqlConnection(conn);
}
return rows;
}
private SqlConnection GetSqlConnection()
{
//dostuff;
return new SqlConnection();
}
private void ProcessError(Exception ex)
{
//dostuff;
}
private void ReturnSqlConnection(SqlConnection conn)
{
//dostuff;
}
}
I have a class where I have a method that is creating a connection string.I want to access that connection string from other windows,but that isn't working.This is my code so far:
My main login is just calling the method from a class on a button click
private void button_Click(object sender, RoutedEventArgs e)
{
Class1 kl = new Class1();
kl.SQLCon(textBox, textBox_Copy);
}
My class looks like this:
class Class1
{
string user = string.Empty;
string pass = string.Empty;
private string ConString = string.Empty;
public string User { get { return this.ConString; } set { this.ConString = value; } }
public void SQLCon(TextBox tb1,TextBox tb2)
{
user = tb1.Text;
pass = tb2.Text;
if (string.IsNullOrWhiteSpace(user) || string.IsNullOrWhiteSpace(pass))
{
MessageBox.Show("Popuni sva polja");
return;
}
SqlConnection con;
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = "DESKTOP";
builder.InitialCatalog = "Manager";
builder.IntegratedSecurity = false;
builder.UserID = user;
builder.Password = pass;
try
{
using (con = new SqlConnection(builder.ToString()))
{
con.Open();
if ((con != null && con.State == System.Data.ConnectionState.Open))
{
ConString = builder.ToString();
MessageBox.Show("Uspesno logovan!" + ConString);
Window1 win = new Window1();
win.ShowDialog();
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
}
Now when from the Window1 I call the method to get ConString,I get nothing,blank.The problem is that it is not looking in the SQLCon for the string value,it is looking it as it is defined at the beggining of the class.
I can get this to work with this solution: before calling ShowDialog,I can have a string in the Window1, that I can pass this value, something like win.stringCon = ConString,and this works.But I want to be able to do this:
Window1 code:
private void button_Click(object sender, RoutedEventArgs e)
{
Class1 myClass = new Class1();
string conn = myClass.User;
MessageBox.Show(conn);
}
SOLUTION: You can't do it the way I imagined. But here is what you can do.
You define a string (conString) in the Window1 that will be you connection string.And you put this line before you call win.ShowDialog():
mw.conString = conString;
This way you have the string in your new window.And with one line you can transport the value from Window1 to some other Window that you will open next.
I've been following the tutorial at http://www.codeproject.com/Articles/43438/Connect-C-to-MySQL on connecting my C# application to an SQL database, but I'm not quite clear on how to actually invoke the connection from within my MainWindow.
I've instantiated the object of the class in my main program, to execute the constructor, but I'm not sure on whether or not my connection is being established, or how to go about doing so. Would really appreciate someone pointing me in the right direction.
My code so far:
DbConnect.cs
namespace SpeedyRent
{
internal class DbConnect
{
private SqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
// Constructor
public DbConnect()
{
Initialize();
}
// Initialize values
private void Initialize()
{
server = "localhost";
database = "rent";
uid = "root";
password = "password123";
string connectionString = "SERVER=" + server + ";" + "DATABASE=" +
database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
connection = new SqlConnection(connectionString);
}
// Open connection to database
private bool OpenConnection()
{
try
{
connection.Open();
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return false;
}
}
// Close connection
private bool CloseConnection()
{
try
{
connection.Close();
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
}
}
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
CurrentDateTimeTextBlock.Text = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss");
var dbConnectObject = new DbConnect();
}
}
I believe the documentation you need is here: http://msdn.microsoft.com/en-us/library/system.data.common.dbconnection%28v=vs.110%29.aspx but in order to open a connection you would do dbConnectObject.open(); and then do whatever you need to do and close with dbConnectObject.close();