I'm creating an application where I connect to an Access database and do several updates. Since I'm not a database programmer this is also a learning experience. I found the following code online but it didn't work until I added the connection.open() line.
So here's my question. I thought that like in other using cases like creating a file it would automatically open the connection and then dispose at the last }. Why did I have to explicitly call out the open command after creating a new connection?
private static void GetAllTableAndColumnNames(string connectionString)
{
using (OdbcConnection connection =
new OdbcConnection(connectionString))
{
connection.Open();
DataTable tables = connection.GetSchema("Tables");
DataTable columns = connection.GetSchema("Columns");
foreach (DataRow row in columns.Rows)
{
Console.WriteLine(row["COLUMN_NAME"].ToString());
Console.WriteLine(row["TABLE_NAME"].ToString());
}
Console.Read();
}
}
Here's the error I got on runtime without the open command.
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.dll
Additional information: Invalid operation. The connection is closed.
When the code reaches the end of a using block and it knows that the Connection object is about to be destroyed it "does you a favour" by ensuring that the connection is properly closed. That is because simply destroying the Connection object without notifying the server would be inconsiderate: server connections are often precious commodities and leaving an orphaned connection "open" on the server would be a Bad Thing.
On the other hand, automatically opening a connection when the Connection object is created (i.e., the using statement itself) would not necessarily be a Good Thing. Perhaps you want to create your Connection object, and then create a whole bunch of other objects that depend on the Connection object (e.g., Command, DataAdapter, etc.). Does the connection actually need to be open while that is taking place? If not, then having the connection open for the whole time might also be inconsiderate if you are connecting to a busy server.
Or, to put it another way, there are very legitimate reasons why a Connection object might switch states between "open" and "closed" while it exists, but the only state it should be in at the moment of its demise is "closed". That's why there is the "auto-close" behaviour but not a corresponding "auto-open".
Using clause is designed to close automaticlly resources when the variable is out of scope. The behaviour in the constructor depends on the implementation: DbConnection descendants don't open the conection in the constructor.
I think that this is because constructor overloads: some overloads doesn't take arguments, so can't open the database.
Related
Is it normally to create an instance "connection" (type of MySqlConnection) every time in every methods in form (I have about 20 methods) and open connection with Open method (in the start of the method) and close connection with Close method (in the end of the method)?
Code (one of my methods):
private void buttonOk_Click(object sender, EventArgs e)
{
MySqlConnection conn = new MySqlConnection(connStr);
conn.Open();
// other code
conn.Close();
}
Or in my case it is better to create a field inside form class and open connection in constructor and close connection in the form_closed method or in destructor?
depends on the implementation of the SqlConnection and the configuration.
In your case (the MySqlConnection) and in most variants of other databases, there is a pooling implementation under the hood.
https://dev.mysql.com/doc/connector-net/en/connector-net-connections-pooling.html
If there is pooling, there is no benefit of keeping a connection open without using it.
If there is a poolsize of 1000 Connections, you can only instanz 1000 of your classes, the next one needs to wait, untill one of the other connection will be closed.
So, its better to open a connection directly, where you need it and as long you need it to not dry out the pool.
And don't forget to dispose the connection
Another reason could be mutlithreading -> connections are not threadsafe. Avoiding a shared connection will avoid threading issues
I need a to get a bit of understanding in this, When you open a connection to a Database can you leave it open?
How does this connection close?
Is it good practise or bad practice?
Currently I have a request to a database that works no problem
oCON.Open();
oCMD.ExecuteNonQuery();
oCON.Close();
However Some of the examples that I have seen are something like this with no database close.
oCON.Open();
oCMD.ExecuteNonQuery();
How would this connection get closed?
Is this bad practice?
I was looking for a duplicate, as this seems to be a common question. The top answer I found is this one, however, I don't like the answer that was given.
You should always close your connection as soon as you're done with it. The database has a finite number of connections that it allows, and it also takes a lot of resources.
The "old school" way to ensure the close occurred was with a try/catch/finally block:
SqlConnection connection;
SqlCommand command;
try
{
// Properly fill in all constructor variables.
connection = new SqlConnection();
command = new SqlCommand();
connection.Open();
command.ExecuteNonQuery();
// Parse the results
}
catch (Exception ex)
{
// Do whatever you need with exception
}
finally
{
if (connection != null)
{
connection.Dispose();
}
if (command != null)
{
command.Dispose();
}
}
However, the using statement is the preferred way as it will automatically Dispose of the object.
try
{
using (var connection = new SqlConnection())
using (var command = new SqlCommand())
{
connection.Open();
command.ExecuteNonQuery();
// Do whatever else you need to.
}
}
catch (Exception ex)
{
// Handle any exception.
}
The using statement is special in that even if an exception gets thrown, it still disposes of the objects that get created before the execution of the code stops. It makes your code more concise and easier to read.
As mentioned by christophano in the comments, when your code gets compiled down to IL, it actually gets written as a try/finally block, replicating what is done in the above example.
You want your SqlConnection to be in a using block:
using(var connection = new SqlConnection(connectionString))
{
...
}
That ensures that the SqlConnectionwill be disposed, which also closes it.
From your perspective the connection is closed. Behind the scenes the connection may or may not actually be closed. It takes time and resources to establish a SQL connection, so behind the scenes those connections aren't immediately closed. They're kept open and idle for a while so that they can be reused. It's called connection pooling. So when you open a connection, you might not really be opening a new connection. You might be retrieving one from the connection pool. And when you close it, it doesn't immediately close, it goes back to the pool.
That's all handled behind the scenes and it doesn't change what we explicitly do with our connections. We always "close" them as quickly as possible, and then the .NET Framework determines when they actually get closed. (It's possible to have some control over that behavior but it's rarely necessary.)
Take a look at the Repository Pattern with Unit of Work.
A connection context should be injected into the class which operates commands to the database.
A sql execution class - like a repository class represents - should not create a connection. It is not testable and hurts the paradigm of SRP.
It should accept an IDbConnection object like in the constructor. The repository should not take care if behind the IDbConnection is an instance of SqlConnection, MysqlConnection or OracleConnection.
All of the ADO.NET connection objects are compatible to IDbConnection.
Some first things that people learned in their early use of MySQL that closing connection right after its usage is important, but why is this so important? Well, if we do it on a website it can save some server resource (as described here) But why we should do that on a .NET desktop application? Does it share the same issues with web application? Or are there others?
If you use connection pooling you won't close the physical connection by calling con.Close, you just tell the pool that this connection can be used. If you call database stuff in a loop you'll get exceptions like "too many open connections" quickly if you don't close them.
Check this:
for (int i = 0; i < 1000; i++)
{
var con = new SqlConnection(Properties.Settings.Default.ConnectionString);
con.Open();
var cmd = new SqlCommand("Select 1", con);
var rd = cmd.ExecuteReader();
while (rd.Read())
Console.WriteLine("{0}) {1}", i, rd.GetInt32(0));
}
One of the possible exceptions:
Timeout expired. The timeout period elapsed prior to obtaining a
connection from the pool. This may have occurred because all pooled
connections were in use and max pool size was reached.
By the way, the same is true for a MySqlConnection.
This is the correct way, use the using statement on all types implementing IDsiposable:
using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
con.Open();
for (int i = 0; i < 1000; i++)
{
using(var cmd = new SqlCommand("Select 1", con))
using (var rd = cmd.ExecuteReader())
while (rd.Read())
Console.WriteLine("{0}) {1}", i, rd.GetInt32(0));
}
}// no need to close it with the using statement, will be done in connection.Dispose
Yes I think it is important to close out your connection rather than leaving it open or allowing the garbage collector to eventually handle it. There are a couple of reason why you should do this and below that I'll describe the best method for how
WHY:
So you've opened a connection to the database and sent some data back and forth along this pipeline and now have the results you were looking for. Ideally at this point you do something else with the data and the end results of your application is achieved.
Once you have the data from the database you don't need it anymore, its part in this is done so leaving the connection open does nothing but hold up memory and increase the number of connections the database and your application has to keep track of and possibly pushing you closer to your maximum number of connections limit.
"But wait! I have to make a lot of database calls in rapid
succession!"
Okay no problem, open the connection run your calls and then close it out again. Opening a connection to a database in a "modern" application isn't going to cost you a significant amount of computing power/time, while explicitly closing out a connection does nothing but help (frees up memory, lowers your number of current connections).
So that is the why, here is the how
HOW:
So depending on how you are connecting to your MySQL database you a probably using an IDisposible object to help manage the connection. Here is what MSDN has to say on using an IDisposable:
As a rule, when you use an IDisposable object, you should declare and
instantiate it in a using statement. The using statement calls the
Dispose method on the object in the correct way, and (when you use it
as shown earlier) it also causes the object itself to go out of scope
as soon as Dispose is called. Within the using block, the object is
read-only and cannot be modified or reassigned.
Here is my personal take on the subject:
Using a using block helps to keep your code cleaner (readability)
Using a usingblock helps to keep your code clear (memory wise), it will "automagically" clean up unused items
With a usingblock it helps to prevent using a previous connection from being used accidentally as it will automatically close out the connection when you are done with it.
In short, I think it is important to close connections properly, preferably with a con.close() type statement method in combination with a using block
As pointed out in the comments this is also a very good question/answer similar to yours: Why always close Database connection?
I am trying to write a background process that checks to see if a database is broken and I am a little bit confused on what exactly would constitute as "broken".
Looking at the official documentation found here on the Microsoft Developers Network for ConnectionState there is a member entitled "broken". At what point would this member result to true, or how exactly would it be used?
This is currently how I am checking if the DB is broken:
public bool DatabaseConnection()
{
bool statusUp = true;
using (var databaseConnection = new SqlConnection(ConfigData.ConnectionStrings.DatabaseConnectionString))
{
try
{
databaseConnection.Open()
}
catch (SqlException ex)
{
const string message = "Could not establish a connection with Database.";
Log.DatabaseStatusDown(message, ex);
statusUp = false;
}
finally { databaseConnection.Close(); }
}
return statusUp
}
I know Using statement leverages the IDisposable class and the connection will be disposed of but I am extra paranoid. Is this efficient? If not, would a more efficient way to determine if my connection is broken would be to do something like this?
public bool DatabaseConnection()
{
using (var databaseConnection = new SqlConnection(ConfigData.ConnectionStrings.DatabaseConnectionString))
{
return databaseConnection.State == ConnectionState.Broken;
}
}
I will be running this process every two minutes, and something tells me the first method I outlined will not be efficient. Would the second method work to determine if my DB is broken? What exactly does Microsoft define as broken for this particular enum?
I wouldn't use ConnectionState.Broken. It is reserved for future use.
The first technique is actually pretty lightweight. All it does is get a connection from the connection pool, which is held locally. Disposing the connection will return the connection to the pool for use by other processes.
I would perhaps consider actually sending a command to the SQL Server, e.g. "SELECT 'ping'" or something lightweight. If you don't get a resultset back it indicates that your SQL Server couldn't service the request for whatever reason.
Not an expert, but I believe broken would indicate that an already connected database connection had an unrecoverable connection issue (Server closed it, etc). It wouldn't be very reliable, and then possibly only detectable after a failed attempt to do something.
It doesn't make sense to check for Broken on a connection you just made. It's only useful for a long-living connection - and it basically tells you to reopen the connection.
It doesn't tell you anything about the state of the database, or the database server. The only thing it tells you is whether the concrete connection is working or not.
If you're always creating new connections, the only thing you care about is whether connection.Open throws an exception or not. And of course, the ExecuteXXX methods etc. - the connection can drop at any point.
I've got an error in my C# application. I'm not sure if it's my program or my website. It's a gaming emulator and it says after 1-2 hours running 'Too many connections'. It also says it on my website.
The line this code is erroring on is below, and it errors and highlights the words connection.Open(); when it crashes. I think it has something to do with not closing the connections.
//C# Coding (In VB)
private static SqlDatabaseClient CreateClient(int Id)
{
MySqlConnection connection = new MySqlConnection(GenerateConnectionString());
connection.Open();
return new SqlDatabaseClient(Id, connection);
}
//Application error
[04:51] Exception - Session -> To many connection[]MySqlData.MySqlClient.MySqlPacket ReadPacket<> # at MysqlData.MySqlClient.MySqlStream.Readpacket<>
at MySql.Data.MySqlClient.NativeDriver.Open<>
at MySql.Data.MySqlClient.Driver.Open<>
at MySql.Data.MySqlClient.Driver.Create
at MySql.Data.MySqlClient.MySqlPool.GtPooledConnection<>
at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver<>
at MySql.Data.MySqlClient.MySqlPool.GetConnection<>
at MySql.Data.MySqlClient.MySqlConnection.Open<>
at Reality.Storage.SqlDatabaeManager.CreateClient in C:\iRP\SqlDatabaseClient.cs:line 24d
It's good practice to place the code accessing your database within a using clause. By doing this you will ensure that your connections are disposed of when it is not used anymore.
C# Too many connections in MySQL
Take a look at that link. You need to use the 'using' statement so the connections are opened and closed properly.