Does SqlDataAdapter close the SqlConnection after the Fill() function or do I need close it myself?
string cnStr = #"Data Source=TEST;Initial Catalog=Suite;Persist Security Info=True;User ID=app;Password=Immmmmm";
cn = new SqlConnection(cnStr);
SqlCommand cmd = new SqlCommand("SELECT TOP 10 * FROM Date", cn);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds);
cn.Close() // ????????
Console.WriteLine(ds.Tables[0].Rows.Count);
Console.WriteLine(cn.State);
In your current usage, it will close 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.
http://msdn.microsoft.com/en-us/library/zxkb3c3d.aspx
I think it's always better to explicitly cater for it yourself with a using statement:
using (SqlConnection conn = new SqlConnection(""))
{
conn.Open();
// Do Stuff.
} // Closes here on dispose.
This is often more readable and doesn't rely on people understanding the inner workings of SqlDataAdapter.Fill, just the using statement and connections.
However, if you know the connection is closed before the adapter uses it (as in, you've just created the connection) and it's not used for anything else, your code is perfectly safe and valid.
Personally, I'd write something like this:
string cnStr = "Data Source=TEST;Initial Catalog=Suite;Persist Security Info=True;User ID=app;Password=Immmmmm";
DataSet ds = new DataSet();
using (SqlConnection cn = new SqlConnection(cnStr))
using (SqlCommand cmd = new SqlCommand("SELECT TOP 10 * FROM Date", cn))
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
conn.Open();
adapter.Fill(ds);
}
As I know you need to close the connection by you own
Best way to do is
using(SqlConnection con = new SqlConnection())
{
// you code
}
this will close you connection automatically
using block in C# comes very handly while dealing with disposable objects. Disposable objects are those objects that can explicitly release the resources they use when called to dispose. As we know .Net garbage collection is non-deterministic so you can’t predict when exactly the object will be garbage collected.
Read this post for more in details : understanding ‘using’ block in C#
Related
I'm using System.Data.SQLite (v1.0.104) in a multi-threaded C# application. When a thread want's to update the DB, it opens a new connection in a using statement (calling the method below) and executes its queries. This seems to work well with the connection string in the following example:
[MethodImpl(MethodImplOptions.Synchronized)]
private SQLiteConnection CreateSQLiteConnection()
{
var connection = new SQLiteConnection("Data Source=myDatabase.sqlite;Version=3");
connection.Open();
return connection;
}
However if I add Pooling=True to the connection string, I can observe the following: One thread is blocking on connection.Open(); indefinitely while the other threads are waiting to enter CreateSQLiteConnection. As far as I can tell from the debugger, at this point in time no thread is actually performing any kind of update to the db.
I already tried setting busy and default timeouts but that didn't change anything. I also know that the sqlite documentation suggests to avoid multiple threads altogether but that is currently not an option.
I've added the Synchronized attribute to avoid potential issues regarding multiple threads simultaneously calling SQLiteConnection.Open but it did not seem to make a difference.
Does anyone know what might cause SQLiteConnection.Open to behave like that or what I could try to get more details about this?
You can use SQLite Version 3 ==> .s3db,
public SQLiteConnection dbConnection = new SQLiteConnection(#"Data Source=E:\Foldername\myDatabase.s3db;");
SQLiteConnection cnn = new SQLiteConnection(dbConnection);
cnn.Open();
string sql = "SELECT * FROM Tble_UserSetUp";
DataSet ds = new DataSet();
SQLiteCommand mycommand = new SQLiteCommand(cnn);
mycommand.CommandText = sql;
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = mycommand;
da.Fill(ds);
cnn.Close();
I use the code below to get data from mySql in C#. When I do that I get the error mentioned below the code. I found some question about the subject but they used DataReader, and I'm not.
MySqlConnection sq = new MySqlConnection("...");
sq.Open();
MySqlCommand sc = new MySqlCommand("select * from users", sq);
DataSet ds = new DataSet();
MySqlDataAdapter da = new MySqlDataAdapter(sc);
da.Fill(ds);
sq.Close();
My Error:
There is already an open DataReader associated with this Connection
which must be closed first.
in your connection string just add "MultipleActiveResultSets=True;"
I don't know if this fixes your issue, however...
Use the using statament for your connection, the command and the dataadapter. This disposes all objects that implement IDisposable and also closes the connection:
using(var sq = new MySqlConnection("..."))
using(var sc = new MySqlCommand("select * from users", sq))
using(var da = new MySqlDataAdapter(sc))
{
DataSet ds = new DataSet();
da.Fill(ds);
// you don't need to open/close the connection with a datadapter
} // but even without a dataadapter the using would have been closed the connection here
as the error said, you aren't closing every connection you open.
Probably because of and exception you get. you can use Tim's suggest:
using(var sq = new MySqlConnection("..."))
using(var sc = new MySqlCommand("select * from users", sq))
using(var da = new MySqlDataAdapter(sc))
or you can use try catch statement:
try
{
// Your code here
}
catch
{
// Whatever code you want here
}
finally
{
da.Close();
sc.Close();
sq.Close();
}
new MySqlCommand("select * from users", sq)
This implementation of the MySqlDataAdapter opens and closes a
MySqlConnection if it is not already open. This can be useful in a an
application that must call the DbDataAdapter.Fill method for two or
more MySqlDataAdapter objects. If the MySqlConnection is already open,
you must explicitly call MySqlConnection.Close or
MySqlConnection.Dispose to close it.
so, no need to open the connection, MySqlDataAdapter will open it when needed.
better to use using statements as other answers.
Further to my recent questions, I've now closed most of the connections that our web application was leaving open. However, the connection created by the function below remains open. Can anyone identify why it is not closing?
public DataTable GetSubDepartment(int deptId)
{
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(Defaults.ConnStr))
{
SqlCommand cmd = new SqlCommand("proc_getDepartmentChild", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#dptParent", deptId));
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
da.Fill(dt);
}
return dt;
}
* EDIT *
Following #HenkHolterman's comment:
I'm using SQL Server Management Studio Activity log to view the open connections. This one is listed as sleeping. SO what you say makes sense. Is there any way I can tell that this is a pooled connection rather than an open one?
Most probably because it went back to the connection pool.
Call
SqlConnection.ClearAllPools();
to clear the pool, then it should disappear. This could sometimes be useful, but is usually not needed.
I would assume that it's hanging in the connectionpool
I have the code below:
using (SqlCommand command = new SqlCommand())
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Connection = new SqlConnection();
command.CommandText = "";
command.Parameters.Add(new SqlParameter("#ExperienceLevel", 3).Direction = System.Data.ParameterDirection.Input);
SqlDataReader dataReader = command.ExecuteReader();
}
Is there any functional impact in declaring the SqlConnection where I currently am declaring it as opposed to like so?:
using (SqlCommand command = new SqlCommand())
using (SqlConnection connection = new SqlConnection())
Thanks
Yes, there's a difference. Disposing the SqlCommand does not automatically dispose the SqlConnection it's associated with. You can leak connections that way, and it will interfere with ADO.NET connection pooling; if you take a look at the database server's activity while this code runs, you'll see new connections being opened and not closed.
You should always be using the second version. In fact, the SqlConnection object is the one that you really need to Dispose. You should always dispose anything that implements IDisposable as soon as possible, but failing to dispose a SqlConnection is particularly dangerous.
Yes, preferably use 2 using blocks, 1 per resource.
In this case you could use just 1 but it should be around the Connection, not around the Command.
But you really don't want to know or care about such details. If a class implements the IDispsoable interface then use its instances in a using() { } block unless there is a special reason not to.
I use the following pattern:
using(var connection = new SqlConnection("ConnectionName"))
using(var command = new SqlCommand())
{
command.Connection = connection;
// setup command
var reader = command.ExecuteReader();
// read from the reader
reader.Close();
}
Yes, the below code will dispose the SqlConnection correctly, the above won't. A using block (implemented internally as try...finally) ensures that the object will be disposed no matter how you exit the block.
i took this code from msdn
string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";
conn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));
}
}
as you can see there is no using for the SqlCommand here, so, does it needs to be ?
You need a using for every object you create that implements IDisposable. That includes the SqlCommand and the SqlConnection.
There are very few exceptions to this rule. The main exception is WCF client proxies. Due to a design flaw, their Dispose method can sometimes throw an exception. If you used the proxy in a using statement, this second exception would cause you to lose the original exception.
You don't NEED to use a using statement, but it is good practice and you SHOULD use it. It allows objects using IDisposable to be disposed of automatically.
http://msdn.microsoft.com/en-us/library/yh598w02(VS.80).aspx
Edited to add link and remove inaccurate statement because #John Saunders is right.