I am trying to have a MySQL connection open in the main form. However, O am having trouble trying use the connection in other forms.
How should I set it up so that I only need to open the connection once in the whole program, and use the same connection to get data from database.
Or should I have a new connection open in each form?
Thank you
It is better to use using statement with SQL connection as follow:
using (SqlConnection connection = new SqlConnection(connectionString))
{
//Your code goes here
}
and make the connection string in App.config file.
You don't want to just leave a connection open the whole time the app is running. It's better to create a single function that you can call repeatedly if your goal is to simplify code readability. The below example is as basic as it gets, but you'll need to do a bit more for stored procedures and Parameter objects not in a query string. All this will do is fill a datatable.
public DataTable RunQuery(string query)
{
//connectionString should come from your configuration or a constant that is a part of this class
DataTable dt = new DataTable();
using (SqlCommand cmd = new SqlConnection(connectionString))
{
cmd.CommandText = query;
cmd.Connection.Open();
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
}
cmd.Connection.Close();
}
return dt;
}
Calling it is easy.
RunQuery("Select * from myData");
Basically, you have to open your MySqlConnection once, and then reuse your connection with using, or by checking it´s state. It is the same as every ADO.NET library. Using the usingstatement you have guarantee that the object will be disposed and all resources released.
This link has everithing you need about working with MySql: https://www.codeproject.com/Articles/43438/Connect-C-to-MySQL
Related
I'm writing some software in C# that will perform queries on Visual FoxPro datafiles over time. I need to be able to close tables, especially those that are opened exclusively ("Mode=Share Exclusive" in the Connection String), but the only way I can seem to do that is by closing the entire OleDbConnection.
The VFP OLE DB Provider supports some syntax from VFP itself, but commands that would close a table in standard VFP, such as USE, either do not work, or throw an exception (I can't recall which command threw an exception at the moment).
Currently, each instance of a class has its own OleDbConnection property, so that if I need to, I'm able to close it and release the table it works on. While this works, it's not optimal, and I'd prefer to have 1 connection instance.
// Elsewhere, ideally one connection for the entire process,
// if I'm able to release locks
public OleDbConnection Connection { get; } = new OleDbConnect();
// ...
if(Connection.State == ConnectionState.Closed) {
Connection.ConnectionString = "Provider=vfpoledb.dll;Data Source=J:\\epdata\\;Mode=Share Exclusive"
Connection.Open();
}
OleDbCommand cmd = new OleDbCommand("SET DELETED OFF", Connection);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT * FROM tran";
OleDbDataAdapter adap = new OleDbDataAdapter(cmd);
DataTable table = new DataTable();
adap.Fill(table);
// Something here to release the lock on the tran table
This works to the point where it will select the data and lock the table for exclusive use by the current OleDbConnection, but I cannot find any way to release that exclusive lock without closing the entire connection, which I'm trying to avoid having to do.
I don't see a point opening a connection exclusively and then using an adapter to fill a table, after which you want to release lock. You don't need a connection in the first place, adapter opens and closes the connection as needed:
DataTable table = new DataTable();
new OleDbDataAdapter("SELECT * FROM tran",
#"Provider=vfpoledb;Data Source=J:\epdata;Deleted=off")
.Fill(table);
I am trying to learn about how to work with databases in C# and I have gotten to a part in a tutorial when I have to work with DataSet , SqlDataAdapter and SqlCommandBuilder.This is the code I wrote in the example in the tutorial:
public void InitData() {
//instantiate the connection
conn = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=\"D:\\Projects IDE\\Visual Studio\\Exercitii\\Console.app\\WindowsFormsApplication1\\WindowsFormsApplication1\\PlanetWrox.mdf\";Integrated Security=True;User Instance=True");
//1.instantiate a new DataSet
dsCustomers = new DataSet();
//2.init SqlDataAdapter with select command and connection
daCustomers = new SqlDataAdapter("SELECT Id ,Name, SortOrder FROM Genre", conn);
// 3. fill in insert, update, and delete commands
SqlCommandBuilder cmdBldr = new SqlCommandBuilder(daCustomers);
// 4. fill the dataset
daCustomers.Fill(dsCustomers, tableName);
}
public void btnUpdateClicked(object sender, EventArgs e) {
// write changes back to DataBase
daCustomers.Update(dsCustomers, tableName);
}
There are a couple of things I do not understand here:
The first thing I noticed is that I do not have to open and close the database.From what limited knoledge I have about databases I know that in order to acces the data you have to open a connection to it and after you are done you have to close it.This must happen somewhere behind the scene.Is that righT? If that is so witch method does that?
The second question is regarding the SqlDataAdapter and SqlCommandBuilder.I do not understand what does SqlCommandBuilder does here.Isen't the SqlDataAdapter the one that is executing the sql query?
The first thing I noticed is that I do not have to open and close the
database.
SqldataAdapter.Fill will open/close the connection for you.
If the IDbConnection is closed before Fill is called, it is opened to
retrieve data and then closed. If the connection is open before Fill
is called, it remains open.
The SqlCommandBuilder generates INSERT, UPDATE, or DELETE statements from the metadata of your provided select-statement. On this way you can call daCustomers.Update and all changes made to the DataSet will automatically be updated in the database.
dsCustomers.Fill opens and closes connection for you.
SqlCommandBuilder creates insert, update, and delete based on your select statement.
ADO.NET handles that task for you, when you Fill your table with data
//instantiate the connection
using (SqlConnection conn = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=\"D:\\Projects IDE\\Visual Studio\\Exercitii\\Console.app\\WindowsFormsApplication1\\WindowsFormsApplication1\\PlanetWrox.mdf\";Integrated Security=True;User Instance=True"))
{
//1.instantiate a new DataSet
dsCustomers = new DataSet();
//2.init SqlDataAdapter with select command and connection
daCustomers = new SqlDataAdapter("SELECT Id ,Name, SortOrder FROM Genre", conn);
// 3. fill in insert, update, and delete commands
SqlCommandBuilder cmdBldr = new SqlCommandBuilder(daCustomers);
// 4. fill the dataset
daCustomers.Fill(dsCustomers, tableName);
}
This would automatically close the connection and Dispose, without you having to bother about it.
Fill will make the all the resources locked that are involved in the process.
Also as per the sql settings it may block other resources too.
If you are using this code for some real time work..Please choose it only if you need this.
For your first thing:
We use conn.open(); to open the connection and conn.close(); to close the connection.
Here in your program you are not connecting to database like to sqlserver. You have provided shown physical path to the file.
See the below for second thing:
SqlCommandBuilder Class
Right, I have been tasked with developing a new application in MVC3 that unfortunately has to integrate very slightly with a classic asp web site. This won't be forever as the old site will get an update at some point, but not yet. In the mean time however the new MVC3 application will need a little bit of access to the database for the old site, which is a old MS Access .mdb whereas the new app will be using sql server 2008.
I would greatly appreciate it if someone could give me some examples of how to connect to the access db, aswell as how to execute sql queries (i am fine writing the sql, just got no idea how to execute against the database from my mvc3 app).
thanks in advance
EDIT: I've not got much experience with the old site, but it appears to use the JET adaptor if that helps! ;-)
Your question requires an answer too extensive to be given in detail
I will give you a check list of things and class to research
Define the connection string used to reach your database [see
here]
Create and open the OleDbConnection
Define your OleDbCommand and the command text to be executed
Create and use an OleDbDataReader to read your data line by line
Create and use an OleDbDataAdapter to read your data and load a
DataSet or DataTable
Now don't forget to close your connection and use parametrized query
string connectionString = Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;Jet OLEDB:Database Password=MyDbPassword;
public void InsertRow(string connectionString, string insertSQL)
{
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
// The insertSQL string contains a SQL statement that
// inserts a new row in the source table.
OleDbCommand command = new OleDbCommand(insertSQL);
// Set the Connection to the new OleDbConnection.
command.Connection = connection;
// Open the connection and execute the insert command.
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// The connection is automatically closed when the
// code exits the using block.
}
}
I created a connection and an SqlReader but forgot to close both of them:
SqlConnection conn = new SqlConnection("connection info");
conn.Open();
string sql = "SQL command HERE";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader reader = cmd.ExecuteReader();
Now when try to run the code again it always gives me this error:
System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.
This link told me how to properly open and close a connection but didn't explain anything on how to close one still running.
I tried shuting down the pc, I tried looking into the database's options on SQL server (found none useful)... I changed the code to do just the close of both the connection and the reader (it compiled and runned but the problem remained after changing back the code).
How can I close this "ghost" connection? Is there any way (brute force) to close all running connections?
[EDIT:] I couldn't really solve the problem. The workaround was to add MultipleActiveResultSets=true to the connection string
I don't think you can access the ghost object, for future, just use using construct where it's possible:
using(SqlConnection conn = new SqlConnection("connection info"))
{
conn.Open();
string sql = "SQL command HERE";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader reader = cmd.ExecuteReader();
....
}
Wrap the creation in a using statement - this will always ensure the connection gets closed:
using(SqlConnection conn = new SqlConnection("connection info"))
{
// your code
}
Looking at all the answers, they seem to tell you how to avoid the problem.
If I'm not mistaken, what you mean is that a connection exists on both the client (your PC) and the server (The sql server) because you forgot to close it, and you're worried about it hanging out there forever.
Think of your connection to the server as a phone conversation. I could hang up on you, but it takes a few seconds for your phone to realize the connection is lost. You may sit there wondering if I've hung up, or just stopped talking. You really don't know. This is what happens on the server when a connection isn't closed properly. (On older landlines, you could leave the phone off the hook and tied up the line indefinitely.)
By closing the connection in code, you are effectively telling the server to close their end of the connection before closing your own. if you FAIL to close the conneciton, it will be closed on your end when the program exits or if you reboot, but the server may sit there with an open connection. (Think of someone sitting there wondering "Did he just hang up on me?")
If I'm not mistaken, what you want to get to is closing it at the SQL server end. (Getting them to "hang up".)
After rebooting, it is absolutely closed on your end. It should clear on its own at the server.
However, if you want to do it yourself, you can clear it at the server in code end using this info: How do you kill all current connections to a SQL Server 2005 database?
A far easier approach would be to just do it in SQL Server Management Studio as described here: http://www.mikebevers.be/blog/2009/07/kill-open-sql-processes-connections/
All of these answers tell you how to avoid the problem, but they don't explain what the problem is.
A SqlDataReader provides forward-only data access, which means that once you have used it and are done, you must close create a new one. See this blog for a detailed explanation. Basically, if you don't close the DataReader, then underthehood it will remain open dedicated to that connection and command.
As others have stated, its best to ensure you close all your resources.
using (SqlConnection connection = new SqlConnection("...")) {
connection.Open();
string sql = "SQL command HERE";
using (SqlCommand cmd = new SqlCommand(sql, con))
using (SqlDataReader reader = cmd.ExecuteReader()) {
// do your stuff
}
}
Truth be told even when you "close" or "dispose" of a connection it does not really go away unless you explicitly disable Pooling in your connection string. You can however do this
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool.aspx
I know this is an old post, and this may help no one. But I saw a opportunity to post what I saw wrong with this question.
First, you are creating a SqlConnection named conn but in your SqlCommand named cmd you are calling con as your connection. This is a problem:
SqlConnection conn = new SqlConnection("connection info");
conn.Open();
string sql = "SQL command HERE";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader reader = cmd.ExecuteReader();
This might be why it's giving you the error:
System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.
Second, to close a conn after you are done you use:
conn.Close();
Third, to close a SqlDataReader you use:
reader.Close();
But you just assigned the SqlDataReader to reader. You never actually opened the SqlDataReader. To open it use:
reader.Read();
Or:
while (reader.Read())
{
// Code
}
Now a proper way to initilaize a connection and a SqlDataReader while opening and close them:
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM TableName;";
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
if (reader.HasRows)
{
strCol1 = reader.GetValue(0).ToString();
}
reader.Close();
}
conn.Close();
}
What is the the best practice for SQL connections?
Currently I am using the following:
using (SqlConnection sqlConn = new SqlConnection(CONNECTIONSTRING))
{
sqlConn.Open();
// DB CODE GOES HERE
}
I have read that this is a very effective way of doing SQL connections. By default the SQL pooling is active, so how I understand it is that when the using code ends the SqlConnection object is closed and disposed but the actual connection to the DB is put in the SQL connection pool. Am i wrong about this?
That's most of it. Some additional points to consider:
Where do you get your connection string? You don't want that hard-coded all over the place and you may need to secure it.
You often have other objects to create as well before your really use the connection (SqlCommand, SqlParameter, DataSet, SqlDataAdapter), and you want to wait as long as possible to open the connection. The full pattern needs to account for that.
You want to make sure your database access is forced into it's own data layer class or assembly. So a common thing to do is express this as a private function call:
.
private static string connectionString = "load from encrypted config file";
private SqlConnection getConnection()
{
return new SqlConnection(connectionString);
}
And then write your sample like this:
using (SqlConnection sqlConn = getConnection())
{
// create command and add parameters
// open the connection
sqlConn.Open();
// run the command
}
That sample can only exist in your data access class. An alternative is to mark it internal and spread the data layer over an entire assembly. The main thing is that a clean separation of your database code is strictly enforced.
A real implementation might look like this:
public IEnumerable<IDataRecord> GetSomeData(string filter)
{
string sql = "SELECT * FROM [SomeTable] WHERE [SomeColumn] LIKE #Filter + '%'";
using (SqlConnection cn = getConnection())
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("#Filter", SqlDbType.NVarChar, 255).Value = filter;
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
Notice that I was also able to "stack" the creation of the cn and cmd objects, and thus reduce nesting and only create one scope block.
Finally, a word of caution about using the yield return code in this specific sample. If you call the method and don't complete your DataBinding or other use right away it could hold the connection open for a long time. An example of this is using it to set a data source in the Load event of an ASP.NET page. Since the actual data binding event won't occur until later you could hold the connection open much longer than needed.
Microsoft's Patterns and Practices libraries are an excellent approach to handling database connectivity. The libraries encapsulate most of the mechanisms involved with opening a connection, which in turn will make your life easier.
Your understanding of using is correct, and that method of usage is the recommended way of doing so. You can also call close in your code as well.
Also : Open late, close early.
Don't open the connection until there are no more steps left before calling the database. And close the connection as soon as you're done.