.NET with MySqlConnection and Connection Pool - c#

I'm beginner working with .NET and Mysql Connection.
To avoid misunderstanding about Connection pool for .NET I want to ask some my question.
Here is simple my code
class Program
{
static void Main(string[] args)
{
string connectionSetting = "Data Source=127.0.0.1;Database=my_table; User Id=root;Password=root" + ";charset=euckr";
MySqlConnection con = new MySqlConnection(connectionSetting);
con.Open();
MySqlCommand command = new MySqlCommand("insert into log(strLog) values('log1')", con);
command.ExecuteNonQuery();
con.Close();
}
}
I've been trying to how to make connection instance for mysql-server, the answer was singleton, But I found many post in StackOverflow and Some answers say Don't share MySql Connection instance and that's all i have to do.
My question is "Who is controlling Connection Pool?"
In the above code, there is no code that relates to controlling the connection pool such as the GetPool, PutPool and so on calls. So I thought database connection pool is controlled in mysql-server side and there is not any other jobs on the .NET side. Is my understanding correct?
If my thought is right, I'll use the following codes.
class dbcp
{
public const string m_ConnectionString = "Data Source=127.0.0.1;Database=my_table; User Id=root;Password=root" + ";charset=euckr";
public MySqlConnection connection;
public dbcp() { }
public void QueryLog(string log)
{
connection = new MySqlConnection(m_ConnectionString);
connection.Open();
string strSQL = "insert into log(strLog) values('log1')";
MySqlCommand cmd = new MySqlCommand(strSQL, connection);
cmd.ExecuteNonQuery();
connection.Close();
}
}
class SomeClassA
{
public dbcp dbHandler;
}
class SomeClassB
{
public dbcp dbHandler;
}
class Program
{
static void Main(string[] args)
{
string connectionSetting = "Data Source=127.0.0.1;Database=gw_ocpp_server; User Id=root;Password=root" + ";charset=euckr";
MySqlConnection con = new MySqlConnection(connectionSetting);
con.Open();
MySqlCommand command = new MySqlCommand("insert into log(strLog) values('log1')", con);
command.ExecuteNonQuery();
con.Close();
}
}

Connection pooling is a technique of creating and managing a pool of connections:
Here's the additional info about connection pooling

Related

How do I solve this SqlConnection in C#?

This is my connection class
class connection
{
public SqlConnection con;
public SqlCommand cmd;
public SqlDataAdapter sda;
String pkk;
public void connectionFunc()
{
con = new SqlConnection(#"Data Source=.;Initial Catalog=payroll;Integrated Security=True");
con.Open();
}
public void dataSend(String SQL)
{
try
{
connectionFunc();
cmd = new SqlCommand(SQL, con);
cmd.ExecuteNonQuery();
pkk = "";
}
catch(Exception)
{
pkk = "error";
}
con.Close();
}
public void dataGet(String SQL)
{
try
{
connectionFunc();
sda = new SqlDataAdapter(SQL, con);
}
catch(Exception)
{
}
}
}
And this is the use of the class:
connection con = new connection();
con.dataGet("Select * from [users] Where Userame = '" + textBox1.Text + "' and Password = '" + textBox2.Text + "'");
DataTable dt = new DataTable();
// this line throws an error
con.sda.Fill(dt);
if(dt.Rows.Count > 0)
{
this.Hide();
Mainpage obj = new Mainpage();
obj.Show();
}
else
{
MessageBox.Show("Invalid UserName Or Password..!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
I get the following error:
An unhandled exception of type 'System.NullReferenceException' occurred in Payroll_Manegement.exe
I don't know what is the issue here if someone could help me that would be great.
To answer your question: the error comes from the fact that your DataTable only is instantiated but not populated before the SqlDataAdapter.Fill is fired, so when the latter tries to do something useful it can only return an exception explaining exactly what is wrong.
Your connection class pains my eyes in terms of insecure variable scope (why use public everywhere?) and non-existent connection pooling. Using a class like this opens up your application for all kinds of insecure horror. Please try to keep things simple if your application is not too complicated; the basics from the .NET Framework should already be enough for your purposes. Just do something similar to the code below (with regard to parameterization of your queries like the others suggested):
string connectionString = "server=myServer;User ID=myUser;Password=myPwd;"; // could also be internal static on class level
string theQuery = "SELECT * FROM dbo.Users WHERE Username = #userName AND Password = #password";
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand(theQuery, sqlConnection))
{
sqlCommand.Parameters.AddWithValue("#userName", textBox1.Text);
sqlCommand.Parameters.AddWithValue("#password", textBox2.Text);
DataTable dataTable = new DataTable();
dataTable.Load(sqlCommand.ExecuteReader());
if (dataTable.Rows > 0)
{
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
sqlDataAdapter.Fill(dataTable);
}
}
}
Alternatively, for the more complex applications you could study the Entity Framework https://learn.microsoft.com/en-us/ef/ef6/get-started first and train yourself in not re-inventing wheels. It will take some time to adapt but will really pay off.
Good luck improving your code!

c# mysqlreader multithread fail

I'm writing a Database class using c# that interacts with a multithread sdk. I should use only one connection(No need to say!) However, I always get errors about connection and datareaders. Anly help appreciated.
Here is the structure of my code
static class Db
{
static MySqlConnection conn = new MySqlConnection(connectionString);
private static void Connect()
{
if (conn.State == ConnectionState.Closed)
conn.Open();
}
private static void DisConnect()
{
if (conn.State == ConnectionState.Open)
conn.Close();
}
static int Insert()
{
Connect();
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.ExecuteNonQuery();
return Convert.ToInt32(cmd.LastInsertedId);
DisConnect();
}
public static DataTable select(string sql) //Especially fails here
{
Connect();
MySqlCommand cmd = new MySqlCommand(sql, conn);
using (MySqlDataReader read = cmd.ExecuteReader())
{
if (read.HasRows){ Some Code... }
}
DisConnect();
}
}
Note that MySqlConnection instance is not guaranteed to be thread safe. You should avoid using the same MySqlConnection in several threads at the same time. It is recommended to open a new connection per thread and to close it when the work is done. Actually, connections will not be created/disposed every time with the Pooling=true; connection string option - connections will be stored in the connection pool. This boosts performance greatly.
I also suggest to use the 'using' clause on creating a connection so that it will be automatically disposed/closed and returned to the connection pool.

C# connecting to a postgres database

This is my first time connecting to a database, but i'm having some problems
using Npgsql;
namespace DBPrj
{
class Program
{
static void Main(string[] args)
{
bool boolfound=false;
NpgsqlConnection conn = new NpgsqlConnection("Server=<ip>; Port=5432; User Id=Admin; Password=postgres.1; Database=Test1"); //<ip> is an actual ip address
conn.Open();
NpgsqlCommand cmd = new NpgsqlCommand();
NpgsqlDataReader dr= cmd.ExecuteReader(); //I get InvalidOperationException : The connection is not open.
if (dr.Read())
{
boolfound=true;
Console.WriteLine("connection established");
}
if(boolfound==false)
{
Console.WriteLine("Data does not exist");
}
dr.Close();
conn.Close();
}
}
}
What could be the problem? Is the NpgsqlConnection string written correctly? Could the database be protected from remote access?
How could I fix this problem?
Thanks in advance!
You never assign your NpgsqlConnection to your NpgsqlCommand and you don't supply a query to execute for your NpgsqlDataReader, fixing that should solve the immediate problems.
Also, wrapping at least your NpgsqlConnection in a using()-statement is a good idea to make sure that the connection is always closed, even if there is an exception.
using Npgsql;
namespace DBPrj
{
class Program
{
static void Main(string[] args)
{
bool boolfound=false;
using(NpgsqlConnection conn = new NpgsqlConnection("Server=<ip>; Port=5432; User Id=Admin; Password=postgres.1; Database=Test1"))
{
conn.Open();
NpgsqlCommand cmd = new NpgsqlCommand("SELECT * FROM Table1", conn);
NpgsqlDataReader dr= cmd.ExecuteReader();
if (dr.Read())
{
boolfound=true;
Console.WriteLine("connection established");
}
if(boolfound==false)
{
Console.WriteLine("Data does not exist");
}
dr.Close();
}
}
}
}
In your connection string you may be missing a semi-colon at the end of database.
Database=Test1"
may need to be;
Database=Test1;"
also - it may be worth wrapping your conn.open() in a try catch statement for user-friendliness and ease of catching errors.
Edit 1:
Just did a little reading. Does NpgsqlCommand need parameters to be passed to it? just in pseudo code, something like;
NpgsqlCommand cmd = new NpgsqlCommand(query, conn);

the perfect way to connect to database?

public class SqlHelper
{
public SqlHelper()
{
}
public static SqlConnection GetConnection()
{
SqlConnection conn = new SqlConnection();
conn.ConnectionString = #"Data Source=.\SQLEXPRESS;AttachDbFilename=" + System.Web.HttpContext.Current.Server.MapPath(#"~\App_Data\learn.mdf") + ";Integrated Security=True;User Instance=True";
return conn;
}
public static SqlDataReader ExecuteReader(string sql)
{
SqlConnection con = GetConnection();
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader dr = null;
try
{
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch
{
con.Close();
return null;
}
return dr;
}
public static Object ExecuteScalar(string sql)
{
SqlConnection con = GetConnection();
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
Object val = null;
try
{
val = cmd.ExecuteScalar();
}
catch
{
con.Close();
return null;
}
finally
{
con.Close();
}
return val;
}
public static DataSet ExecuteDataSet(string sql)
{
SqlConnection con = GetConnection();
SqlCommand cmd = new SqlCommand(sql, con);
DataSet ds = new DataSet();
SqlDataAdapter adapt = new SqlDataAdapter(cmd);
try
{
adapt.Fill(ds);
}
catch
{
con.Close();
}
return ds;
}
public static void ExecuteNonQuery(string sql)
{
SqlConnection con = GetConnection();
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
try
{
cmd.ExecuteNonQuery();
}
finally
{
con.Close();
}
}
}
This is the Class which I use to implement every access to my database . But I think that the way I do connection with the database is a little bit overblown cause I have to hit the Connect function every time I need something . As well as other users going to do the same which kills the performance.
So what is the perfect way to connect with the database - and to stay connected if that better . Note that I use the database in many pages!
Thanks
First, you should be using "using" statements to ensure that all your ADO.NET objects are properly disposed of in the event of a failure:
public static void ExecuteNonQuery(string sql)
{
using(var con = GetConnection())
{
con.Open();
using(var cmd = new SqlCommand(sql, con))
{
cmd.ExecuteNonQuery();
}
}
}
However, having said that, I don't really see a problem with this approach. The advantage is that the connections, commands, adapters and whatnot are properly disposed of every time you execute a bit of SQL. If you were to make a single static SqlConnection instance, you'd escalate the chances that the connection is already in use (when, for example, iterating over the contents of a SqlDataReader).
If you are really concerned about it, provide overloads that take a connection as an extra parameter:
public static void ExecuteNonQuery(string sql, SqlConnection connection)
{
using(var cmd = new SqlCommand(sql, con))
{
cmd.ExecuteNonQuery();
}
}
This way, callers can either execute a bit of SQL that doesn't require multiple calls, or they can call your GetConnectionMethod to obtain a connection, and pass it to multiple calls.
If this is used for a web site then you have to consider that between requests for pages, even from the same browser, your server state will be torn down (in general terms) so there's nothing really to be gained from trying to maintain your SQL connection between pages. That's the first thing.
If each page is the result of a single database connection then you are probably as optimised as you really need to be, if you are making several connections over the generation of a page then you may want to look at keeping a connection alive until you have finished retrieving data; either by maintaining the connection or optimising your data retrieval to limit the back and forth between your app and the db.
Maintaining a database connection is the job of the connection pool, and not the connection consumer. The best practice is to aquire a connection as late as possible and release it as soon as possible.
using(var connection = new SqlConnection(YourConnectionStringHelperFunction())
{
}
One thing that YOu might take into consideration is the Dependency Injection PAttern and some IoC controller. If every page needs to have this connection make this an injectable property (constructor probably wont work unless You implement some kind of infrastructure classes like Request) use some container (Unity, Castle, StructureMap) pack the needed things up (maybe cache, maybe some other things) and let the container do the magic (by magic I mean tons of boilerplate code) for You.
luke
First you can write a seperate class like this :
Get method for getting data (with a Select query) and Set method for manipulating data (Insert, Update, Delete)
using System.Data;
using System.Data.Odbc;
using System.Data.SqlClient; //using this you can replace instead odbc to sql
// Example SqlCommand, SqlDataAdapter
class DataBaseConnection
{
private OdbcConnection conn1 = new OdbcConnection(#"FILEDSN=C:/OTPub/Ot.dsn;" + "Uid=sa;" + "Pwd=otdata#123;"); //"DSN=Ot_DataODBC;" + "Uid=sa;" + "Pwd=otdata#123;"
//insert,update,delete
public int SetData(string query)
{
try
{
conn1.Open();
OdbcCommand command = new OdbcCommand(query, conn1);
int rs = command.ExecuteNonQuery();
conn1.Close();
return rs;
}
catch (Exception ex)
{
conn1.Close();
throw ex;
}
}
//select
public System.Data.DataTable GetData(string sql)
{
try
{
conn1.Open();
OdbcDataAdapter adpt = new OdbcDataAdapter(sql, conn1);
DataTable dt = new DataTable();
adpt.Fill(dt);
conn1.Close();
return dt;
}
catch (Exception ex)
{
conn1.Close();
throw ex;
}
}
}
in your form you can make object to that database connection class
DataBaseConnection db = new DataBaseConnection();
now you cal call get set with your get set method as following
string sqlSpecialHoliyday = "SELECT * FROM Holiday WHERE Date_Time='" + selectdate + "' AND IDH='50'";
DataTable dtAdditionalholily = db.GetData(sqlSpecialHoliyday);
AD you can Set Data Using Set method
string insertloginlog = "INSERT INTO Login_Log (Service_No, Machine_Name) VALUES ('" + serviceID + "','" + machiname + "')";
int ret = db.SetData(insertloginlog);
Hope This will help!

SQL Server insert

I have a simple two-field form that stores its data in the database. For some reason, it isn't working. I have verified that the connection string works, as it is used in another project I made.
I didn't include the beginning of the first class or its page load.
Code:
protected void btnSubmit_Click(object sender, EventArgs e)
{
string Name = txtName.Text;
string Description = txtSpecial.Text;
string method = string.Format(
"INSERT INTO RbSpecials (Name,Description,Active) VALUES ('{0}','{1}','1')",
Name,
Description);
RbConfiguration mySql = new RbConfiguration();
try
{
mySql.Sql_Connection(method);
}
catch
{
}
}
}
public class RbConfiguration
{
string DbConnectionString = "System.Configuration.ConfigurationManager.ConnectionStrings['RBConnectionString'].ConnectionString";
public void Sql_Connection(string queryString)
{
SqlConnection conn = new SqlConnection(DbConnectionString);
SqlCommand cmd = new SqlCommand(queryString, conn);
conn.Open();
conn.Close();
}
}
You never execute your SQL command:
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
And your connection string is wrong (ditch the double quotes):
string DbConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RBConnectionString"].ConnectionString;
Well without knowing the error, I'll give it a shot anyway.
string DbConnectionString = "System.Configuration.ConfigurationManager.ConnectionStrings['RBConnectionString'].ConnectionString";
Should be
string DbConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RBConnectionString"].ConnectionString;
And as Adam says, you never actually execute your Query.
The Sql_Connection-method, only opens a connection, and then closes it again, without actually doing anything.
Try this instead:
public void Sql_Connection(string queryString)
{
using( SqlConnection conn = new SqlConnection(DbConnectionString) )
{
SqlCommand cmd = new SqlCommand(queryString, conn);
conn.Open();
cmd.ExecuteNonQuery();
}
}
Check your connection string code must not be a string its class which is getting connection string from web.config, so it should be like this
string DbConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["RBConnectionString"].ConnectionString;
You did not execute your SQlCommand, so will it insert the data, do this
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
its not the cause but the best practice to not to make your code vulnerable to SQLINjection, try this article
How To: Protect From SQL Injection in ASP.NET

Categories