I want to re-use the same SQLConnection accros different methods within the class. What I'm doing right now (testing only) is creating and opening a connection in the constructor:
SQLConnection Connection;
Constructor(string connection_string)
{
this.Connection = new SqlConnection(connection_string);
this.Connection.Open();
}
then I use "this.Connection" inside methods and finally use this.Connection.Close() and Dispose() at the end when the object is not needed anymore. From what I know it would be cleaner to use 'using' inside each method like this (the constructor would only set the connection_string):
using (SqlConnection connection = new SqlConnection(connection_string)) {
connection.Open(); ...
}
Because of connection pooling, only one connection is actually used, despite the above 'using' line being placed in multiple methods (e.g. when they are called one after another), correct? However, wouldn't this create many SQLConnection instances where only one would be needed? E.g.:
MyClass obj(some_string);
obj.Method1(); // calls 'using SqlConnection connection = new SqlConnection'
obj.Method2(); // calls 'using SqlConnection connection = new SqlConnection'
obj.Method3(); // calls 'using SqlConnection connection = new SqlConnection'
So what's the proper, optimal way to share the SQLConnection?
You are correct about all your statements. However you are missing one important point: creating lots of instances of a type in .NET is not necessarily a bad thing!
You should not create a single connection instance in the constructor
You should create a connection locally, when needed
It is best practice to use the using paradigm when creating disposable objects
You should make a habit of calling Dispose on disposable objects in a try...finall block (if not using using) - in case your specific scenario doesn't land itself well for the use of usings; for instance using asynchronous methods)
Finally, you should not keep a SQL connection open for longer than you need it to be. Again, just take advantage of connection pooling in the ADO.NET provider for SQL Server
Now, the reason it's not a problem to create lots of instances of the Connection type is because creating objects in the .NET CLR is optimized (fast memory allocation and object instantiation) and relatively pain free (no need to worry about releasing memory thanks to Garbage Collection).. You also have the benefits of connection pooling in case of the ADO.NET providers so really, you shouldn't concern yourself with managing the number of instances of this Type.
It should be obvious that in other cases (such as heavy/large objects) creating lots of them can have an impact on memory pressure and performance. So always asses the situation as best as you can..
Related
I'm not sure if i'm just having a dumb moment here or I generally do not understand but can someone explain to me why this will run:
using System.Data.SqlClient;
using System.Configuration;
public void SomeMethod()
{
using(SqlConnection dbConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString))
{
using(SqlCommand qry = new SqlCommand(someSqlString, dbConnection))
{
dbConnection.Open();
using(SqlDataReader reader = qry.ExecuteReader())
{
...
}
}
}
}
and this will not run throwing an InvalidOperationException (The ConnectionString property has not been initialized) when it hits dbConnection.Open():
using System.Data.SqlClient;
using System.Configuration;
private SqlConnection dbConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString);
public void SomeMethod()
{
using(dbConnection)
{
using(SqlCommand qry = new SqlCommand(someSqlString, dbConnection))
{
dbConnection.Open();
using(SqlDataReader reader = qry.ExecuteReader())
{
...
}
}
}
}
The second example will run (at least it should)... but only the first time you call SomeMethod(). This is because after the first call to the method, you have Dispose()'d the connection object.
ADO.Net has a built-in feature called Connection Pooling that intelligently re-uses the underlying database connection resources. For the most part, you should not try to use the same Dbconnection object over and over. Instead, just re-use the connection string, create the connection objects as you need them, and Dispose() of them as soon as possible when done. Otherwise, you are conflicting with the built-in connection pooling and making things worse, rather than better.
In other words, the first sample is the correct way to do this. It's faster and more efficient than the second, even though the second seems to save you an object allocation here and there.
About the only time you should try to re-use a connection object is when you're going to have a bunch of queries in a tight loop, such that you might open the connection once, execute a bunch of queries one after the other, and then close it when you've finished the whole batch. And even then, most of the time when I've seen this the code was better off refactored in some way to group the sql statements into a single batch.
MSDN explains:
You can instantiate the resource object and then pass the variable to
the using statement, but this is not a best practice. In this case,
the object remains in scope after control leaves the using block even
though it will probably no longer have access to its unmanaged
resources. In other words, it will no longer be fully initialized. If
you try to use the object outside the using block, you risk causing an
exception to be thrown. For this reason, it is generally better to
instantiate the object in the using statement and limit its scope to
the using block.
So, to simplify it...
using statement ensures that the object will be disposed after code block is executed and will ensure the object will go out of scope. So, in your second example, you're using it wrong, and the connection is no longer managed so it behavies unpredictably.
Sometimes I see people like to dispose just anything after use regardless of how frequently they're being used (probably not related to SQLite question, but I am dealing with SQLite as of now, I'm puzzled) -- or perhaps I am mistaken. This has caused a massive confusion for me.
For example (taken from elsewhere):
using(var con = new SQLiteConnection(conString))
using(var cmd = new SQLiteCommand(con))
{
con.Open();
// ...
} // also closes the connection
My question is, should I store the SQLiteConnection and SQLiteCommand objects in the field, and use the method .Open(), .Close() to handle the database connection without disposing them at all until application termination -- or dispose them into the Garbage Collection like it's not really an elegant idea in my perspective?
Edit: If one says dispose, then why? I need better answers, I need the true reason why, not because of pooling, and whatnot. I need to know what exact problems could arise other than human-prone errors, and provide an example or perhaps a link to the example.
For example the class field:
private static SQLiteConnection sQLiteConnection; /// <summary>SQLiteConnection.</summary>
public static SQLiteConnection SQLiteConnection { get { return sQLiteConnection; } }
private static SQLiteCommand sQLiteCommand; /// <summary>SQLiteCommand.</summary>
public static SQLiteCommand SQLiteCommand { get { return sQLiteCommand; } }
Where the private fields are initialized with a private method, and the objects are to be reused without disposing them; Hence the read-only properties.
Edit 2: For clearer clarification, are you people misreading? I am saying "reusing". Which means one is created, and stored somewhere in the field to be reused. I am storing it in the static field in a static class to be reused until the application is closed. Tell me, why do I have to dispose it?
Why, do, I, have, to, dispose, it? If, I, were, to, "reuse", it? Why?
Connections are pooled by .NET, so creating them generally isn't an expensive operation. Using the "standard" approach is generally much cleaner that trying to keep track of if a connection is open or closed, etc.
Unless you have measurable problems with connection I would stick with the idomatic approach of creating them, using them, and disposing of them.
I recently posted (and promptly deleted, when I decided the question was irrelevant to the actual problem) a question about SqlConnection losing its Database information when the scope of "ChangeDatabase" ends. Example:
//Other code...
dbConn = new SqlConnection(dbConnBuilder.ConnectionString);
dbConn.Open();
dbConn.ChangeDatabase(currentDatabase);
dbConn.Close();
}
My questions:
Is it considered bad practice to hold onto a SqlConnection object and open and close it whenever you need it when you'll only ever have ONE connection of a given type?
Why does dbConn.Database not remember currentDatabase after ChangeDatabase (a method not a variable) 'Goes out of scope'? (Heck, I didn't know methods like ChangeDatabase could know about scope).
My connection string was:
Data Source=server.name.com;Persist Security Info=True;User ID=username;Password=password
Thanks guys, let me know if I can give you more information, still learning to use S.O.
Calling Close() completely destroys the object, so you should not be reading any of its properties after.
In fact, there should even be an "after" because you shouldn't be calling Close(). Instead, instantiate the connection in a using block, so that it'll call Dispose(), which does the same thing as Close(), but is guaranteed to do so no matter how you leave the block.
So just make sure to call changedatabase every time you need to execute a statement :-)
public class db
{
public static string connectionString =
WebConfigurationManager.ConnectionStrings["connectString"].ConnectionString;
public static SqlConnection OpenConnection()
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
return connection;
}
}
I see code like this and it screams WRONG! It's for an ASP.NET (2.0). I understand it to be wrong.
For one you shouldn't open the SqlConnection and return it and two why would you make a static SqlConnection? Won't that create problems if multiple people are trying use it at the same time?
What is static is OpenConnection() the Method which returns the connection. A new connection gets returned each time however (the assumption is that caller will be in charge of disposing of this connection object when appropriate).
In other words, the db class shown is not a singleton at all. The confusion may arise from the fact that one does not need to instantiate an instance of db in order to use its OpenConnection() method (since it is static), and the rest of the code may contain multiple snippets like
myConn = db.OpenConnection();
-- then do something with myConn
I'm not 100% sure what the question is, but to answer this
Won't that create problems if multiple
people are trying use it at the same
time?
no, there wouldn't be problems because each call to OpenConnection() constructs a new SqlConnection instance. That doesn't mean the code isn't garbage for other reasons. I at least hope calls to this method look something like this:
using(var conn = db.OpenConnection())
{
// stuff
}
You can't just say "Screams of being wrong" and then apply the term "Singleton" incorrectly. Why is a single static connection a poor approach? It you do not recreate it each time, then your entire application can share the connection. Do you need to create, open and close for each frigg'n sql call, that screams of stupid. Either way ADO should manage this.
Connection objects must be scoped to the method that executes the transaction.
Sharing the same connection object between threads will corrupt the connection pool.
See this question on SQLDataReader.GetOrdinal() fails rarely with IndexOutOfRange.
We have a SQL utility class that takes the name of a stored procedure an its input parameters, and returns the results in datatable. The reasoning behind this is so that we don't have to worry about forgetting to close connections and having connection leaks. Also so that we can reduce code by not having to recreate datadapters and datareaders in our data access layers.
The problem I have with this is that we're populating a datatable so that we can loop through it to create our objects, so we're basically using it like a datareader. I've read about classes that will return a datareader or dataadapter. But the problem with this is either client has to open and close connections, or you have to close the connection in a Finalize method. It seems that you wouldn't want garbage collection being responsible for closing your database connections.
To sum up, we want to have a class so that we can reduce code by not having to create datareaders for every query and so that we can ensure database connections are closed.
What is the best way of handling this?
UPDATE: Still thinking about this, but so far it seems that the best practice is to still return a datareader, use CommandBehavior.CloseConnection, and then trust who ever uses the class to call dr.Close()?
Have you considered the Microsoft Enterprise Library?
public List<User> GetUsers()
{
List<User> result = new List<User>();
Database db = new
Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase(this.connectionString);
DbCommand cmd = db.GetStoredProcCommand("GetUsers");
using (IDataReader rdr = db.ExecuteReader(cmd))
{
while (rdr.Read())
{
User user = new User();
FillUser(rdr, user);
result.Add(user);
}
}
return result;
}
We use something like this and it performs very well under high volume.
public SqlDataReader ExecuteReader(string command, SqlParameter[] parameters)
{
SqlDataReader reader = null;
using (SqlConnection conn = new SqlConnection())
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = command;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange(parameters);
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
return reader;
}
DataTables are not considered best practice for several reasons including their bloat and lack of type safety.
I have the same structure - utility classes with methods that fetch the data and return filled DataTables (or fill/update a DataTable passed in to them) - for exactly the same reasons: keeping the database connections separate from the rest of the code and ensuring they are opened only when required and closed asap. Especially since the data is stored in various back-end systems, and I want to present only one interface to my application and not have it worry about the details.
There is one difference to your situation: We don't (in general) create objects from the rows in the DataTables, but rather work directly on the data in the rows. I find working with DataTables simple and efficient.
Other than that, I personally don't see anything wrong with this approach and find that it works very well for our purposes.
Returning a datareader doesn't work in a lot of scenarios. At a lot of places, direct connections to the database from the client machine are not allowed in production (for good reason). So you have to serialize the objects you are retrieving. I can think of designs that would allow you to persist a datareader in whatever class you use for remoting/serialization on the server side but returning items across http or nettcp in row by agonizing row fashion likely does not offer much benefit.
Are you serializing these objects? If so, your choices boil down to Datatable, Dataset, or custom objects. Custom objects, if written well, perform and serialize the best but you have to write concurrency in addition to a bunch of other functionality.
IMO, since ADO.Net 2.0, datatables can perform well even in large scale remoting situations. They provide a special binary remoting format and are simple to work with. Throw in some compression and you're not even using a lot of bandwidth for your large data sets.
well, if you plan to use this class inside of web pages you can register the utility class with the page's unload event. In the event sink you can write your logic to close the database connection. Check out this tip on codeproject for more ideas.
however this solution won't work for use inside web methods (web services). I suppose you'd have to adapt the technique for web service use. Your last line in the web method should should be an event call. So when you write your web service class, define an event called WebMethodCompleted. You'd probably get a reference to the instance of the web service via the technique mentioned in the article. Once you get a reference you can register tthe event in your utility class. Just remember to invoke the event in the web method.
Happy programming.