Does using statement close all kinds of streams in it? - c#

I have using statement to close the OleDbConnection and then I'm working with the reader.
I'm wondering if I have to close the reader at the end or I can rely on the using statement to close it.
I've got the following code:
string connectionString = #"Some connection";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
string query = "SELECT ID, Name, \[Position\] FROM Players";
OleDbCommand command = new OleDbCommand(query, connection);
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine($"ID.{reader\[0\]} {reader\[1\],-18}{reader\[2\]}");
}
reader.Close();
}

As a rule of thumb:
Use the using-statement for everything that implements IDisposable.
So yes, use the using also for the OleDbDataReader and the OleDbCommand.
But you can simplify all to this:
using var connection = new OleDbConnection(#"Some connection");
using var command = new OleDbCommand("SELECT ID, Name, Position FROM Players", connection);
connection.Open();
using OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine($"ID.{reader[0]} {reader[1],-18}{reader[2]}");
}

Related

Ado.Net: Does closing SqlCommand cause closing DataReader

Today I looked through some legacy code and I have began worrying. It is required to close a DataReader explicitly.
My question is: does closing the SqlCommand close the associated DataReader as well?
This is my code:
using (var conn = new SqlConnection(this.ConnectionString))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "House_GetHouseById";
SqlCommandBuilder.DeriveParameters(cmd);
cmd.Parameters["#HouseId"].Value = houseId;
var reader = cmd.ExecuteReader())
while (reader.Read())
{
}
}
}
In this snippet from msdn command is not closed explicitly:
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlCommand command =
new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Call Read before accessing data.
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
// Call Close when done reading.
reader.Close();
}
No. SqlCommand.Dispose is essentially a no-op¹, and it won't close your SqlDataReader.
Technically, closing the SqlConnection should close all resources, see this question for details:
Is closing/disposing an SqlDataReader needed if you are already closing the SqlConnection?
However, this is bad practice -- you are relying on an implementation detail of the SqlClient library. The "correct" way would be to dispose (via Dispose or using) everything that is IDisposable. Thus, your code should be written as follows:
using (var conn = new SqlConnection(this.ConnectionString))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "House_GetHouseById";
SqlCommandBuilder.DeriveParameters(cmd);
cmd.Parameters["#HouseId"].Value = houseId;
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// do something
}
}
}
}
¹ Note that this is not true for the command classes of other libraries such as OleDbCommand and SqlCeCommand, so don't get in the habit of not disposing commands.
You could always wrap the datareader in a using directive so that the command is closed as soon the execution is out of the scope,just like the sqlcommand
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
} // reader is closed here
reader.Close(); //is another way but its too easy to be forgotten.

C# ASP.NET error: There is already an open datareader associated with this command which must be closed first

I keep getting this error
There is already an open datareader associated with this command which must be closed first.
at this line of code:
using (SqlDataReader rd = command.ExecuteReader())
I have tried to close all other SqlDataReader's in class but it didn't work.
public int SifreGetir(string pEmail) {
SqlCommand command = con.CreateCommand();
command.CommandText = #"SELECT Sifre FROM Kullanici WITH (NOLOCK) WHERE email=#email";
command.Parameters.Add("#email", SqlDbType.VarChar);
command.Parameters["#email"].Value = pEmail;
using (SqlDataReader rd = command.ExecuteReader())
{
rd.Read();
string pass = rd["Sifre"].ToString();
int p = Convert.ToInt32(pass);
return p;
}
}
Try implementing your code in the below format
using(SqlConnection connection = new SqlConnection("connection string"))
{
connection.Open();
using(SqlCommand cmd = new SqlCommand("your sql command", connection))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
}
}
}
The using statement will ensure disposal of the objects at the end of the using block
try this:
public int SifreGetir(string pEmail) {
SqlConnection con = new SqlConnection("Your connection string here");
con.Open();
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new DataSet();
SqlCommand command = new SqlCommand(#"SELECT Sifre FROM Kullanici WITH (NOLOCK) WHERE email=#email",con);
command.CommandType = CommandType.Text;
command.Parameters.Add("#email", SqlDbType.VarChar).Value = pEmail;
da.Fill(ds);
foreach(DataRow dr in ds.Tables[0].Rows)
{
string pass = dr["Sifre"].ToString();
int p = Convert.ToInt32(pass);
return p;
}
con.Close();
}
You have used Using Keyword for SQL Reader but There is nothing to take care of your command and connection object to dispose them properly. I would suggest to try disposing your Connection and command both objects by Using keyword.
string connString = "Data Source=localhost;Integrated " + "Security=SSPI;Initial Catalog=Northwind;";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new;
cmd.CommandText = "SELECT ID, Name FROM Customers";
conn.Open();
using (SqlDataReader rd = command.ExecuteReader())
{
rd.Read();
string pass = rd["Sifre"].ToString();
int p = Convert.ToInt32(pass);
return p;
}
}

Best practices with oracle connection in C #

We use oracle database connection and our class database access does not have a dispose or close. It interferes with something or performance of the application? I saw this example:
string oradb = "Data Source=ORCL;User Id=hr;Password=hr;";
OracleConnection conn = new OracleConnection(oradb); // C#
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "select * from departments";
cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
label1.Text = dr.GetString(0);
conn.Dispose();
And I realized that it opens the connection and then kills her. This is correct? Is there any other better?
I'm leaving my connection open and then ends up being closed for a while. I think that's it. This so wrong?
Use the Using statement with disposable objects. In particular with any kind of connection and datareaders
string oradb = "Data Source=ORCL;User Id=hr;Password=hr;";
using(OracleConnection conn = new OracleConnection(oradb))
using(OracleCommand cmd = new OracleCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "select * from departments";
cmd.CommandType = CommandType.Text;
using(OracleDataReader dr = cmd.ExecuteReader())
{
dr.Read();
label1.Text = dr.GetString(0);
}
}
Here you could read about the Using statement and why it is important. Regarding the connection and readers, you should enclose the objects with the using statement to be sure that everything is properly closed and disposed when you exit from the using block ALSO in case of exceptions

How to Simplify C# query Execution?

I am programmer in asp.net. I am using C#. I have written very lengthy code for query execution in each time. How to re-factor and organize the following code?
MySqlConnection connection = new MySqlConnection(connstring);
string query = "Select fo_region_Name from fo_region where fo_region_DeleteStatus=0";
MySqlCommand command = new MySqlCommand(query, connection);
MySqlDataReader reader;
connection.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
ddl_Country.Items.Add(UppercaseFirst(reader[0].ToString()));
}
connection.Close();
query = "Select Fo_Nationality_Name from fo_Nationality a, Fo_region b where a.Fo_Nationality_Type=1 and "
+ "LEFT(a.Fo_Nationality_Code,2)=LEFT(b.fo_region_Name,2) and a.Fo_Nationality_DeleteStatus=0 and "
+ "b.fo_region_DeleteStatus=0 Union Select Fo_Nationality_Name from fo_nationality where Fo_Nationality_DeleteStatus=0";
command = new MySqlCommand(query, connection);
connection.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
ddl_Nationality.Items.Add(UppercaseFirst(reader[0].ToString()));
}
connection.Close();
query = "select mcs_CreditCard_CardName from mcs_creditcard where mcs_CreditCard_DeleteStatus=0";
command = new MySqlCommand(query, connection);
connection.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
ddl_CreditCard.Items.Add(UppercaseFirst(reader[0].ToString()));
}
connection.Close();
Some thoughts:
Use multiline strings to format your SQL statements.
There is no need to close and reopen the connection betwween each command execution.
There is also no need to create new connection and command objects (in this case)
If you have parameters on the command objects, it is easier to create new command objects, rather than clearing out the old parameters
Use var statements to have the C# compiler automatically determine the variable type for you.
Wrap objects that need to be disposed, in a using block.
using (var connection = new MySqlConnection(connstring)) {
connection.Open();
using (var command = new MySqlCommand()) {
MySqlDataReader reader;
command.CommandText = #"
SELECT fo_region_Name
FROM fo_region
WHERE fo_region_DeleteStatus=0
";
using (reader = command.ExecuteReader()) {
while (reader.Read()) {
ddl_Country.Items.Add(UppercaseFirst(reader[0].ToString()));
}
}
command.CommandText = #"
SELECT Fo_Nationality_Name
FROM fo_Nationality a,
Fo_region b
WHERE a.Fo_Nationality_Type = 1
AND LEFT(a.Fo_Nationality_Code,2) = LEFT(b.fo_region_Name,2)
AND b.fo_region_DeleteStatus=0
UNION SELECT Fo_Nationality_Name
FROM fo_nationality
WHERE Fo_Nationality_DeleteStatus=0
";
using (reader = command.ExecuteReader()) {
while (reader.Read()) {
ddl_Nationality.Items.Add(UppercaseFirst(reader[0].ToString()));
}
}
command.CommandText = #"
SELECT mcs_CreditCard_CardName
FROM mcs_creditcard
WHERE mcs_CreditCard_DeleteStatus = 0
";
using (reader = command.ExecuteReader()) {
while (reader.Read()) {
ddl_Nationality.Items.Add(UppercaseFirst(reader[0].ToString()));
}
}
}
}
With LINQ (add a using System.Data.Common statement):
using (reader = command.ExecuteReader()) {
/*while (reader.Read()) {
ddl_Country.Items.Add(UppercaseFirst(reader[0].ToString()));
}*/
ddl_Country.Items.AddRange((
from DbDataRecord row in reader
select new ListItem(
UppercaseFirst(reader.GetString(0))
)
).ToArray());
}
Maybe use can use EnterpriseLibrary, to reduce amount of code that deals with database.

Multiple SQL queries asp.net c#

I need to run several queries inside one function, will I have to create a new SqlConnection for each? Or having one connection but different SqlCommands works too?
Thanks,
EDIT: Will this work?
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(query1, conn))
{
cmd.ExecuteNonQuery();
}
using (SqlCommand cmd = new SqlCommand(query2, conn))
{
cmd.ExecuteNonQuery();
}
using (SqlCommand cmd = new SqlCommand(query3, conn))
{
cmd.ExecuteNonQuery();
}
}
Using the MDSN Documentation as a base:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql1 = "SELECT ID,FirstName,LastName FROM VP_PERSON";
string sql2 = "SELECT Address,City,State,Code FROM VP_ADDRESS";
using (SqlCommand command = new SqlCommand(sql1,connection))
{
//Command 1
using (SqlDataReader reader = command.ExecuteReader())
{
// reader.Read iteration etc
}
} // command is disposed.
using (SqlCommand command = new SqlCommand(sql2,connection))
{
//Command 1
using (SqlDataReader reader = command.ExecuteReader())
{
// reader.Read iteration etc
}
} // command is disposed.
// If you don't using using on your SqlCommands you need to dispose of them
// by calling command.Dispose(); on the command after you're done.
} // the SqlConnection will be disposed
It doesn't matter which way you go.
SqlConnections are pooled by the operating system. You could literally open and close a connection thousands of times in a row and not incur any performance or other penalty.
How it works is:
Application makes a request to create a db connection (var c = new SqlConnection(...))
The Operating Systems connection pool looks to see if it has a connection sitting idle. If it does, you get a reference to that. If not then it spins up a new one.
Application indicates it is finished with the connection (c.Dispose())
Operating System keeps the connection open for a certain amount of time in case your app, or another one, tries to create another connection to that same resource.
If that connection stays idle until a timeout period passes then the OS finally closes and releases.
This is why the first time you make a connection to a database it might take a second to start before the command(s) can be processed. However if you close it and reopen it then the connection is available immediately. More information is here: http://msdn.microsoft.com/en-us/library/8xx3tyca(v=vs.110).aspx
Now, as to your code, generally speaking you open 1 SqlConnection each time you make a SqlCommand call; however, it is perfectly acceptable/reasonable to make multiple SqlCommand calls while within the same block under the SqlConnection using clause.
Just bear in mind that you do NOT want to keep a SqlConnection object hanging around in your code for any longer than is absolutely necessary. This can lead to a lot of potential issues, especially if you are doing web development. Which means it's far better for your code to open and close 100 SqlConnection objects in rapid succession than it is to hold onto that object and pass it around through various methods.
Having one SqlConnection and many SqlCommands will work fine, however you must make sure that you dispose of any SqlDataReaders that are returned from previous commands before attempting to run additional commands.
using (SqlConnection conn = new SqlConnection())
{
conn.Open()
using (SqlCommand cmd = new SqlCommand("SELECT myrow FROM mytable", conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Handle first resultset here
}
}
using (SqlCommand cmd = new SqlCommand("SELECT otherrow FROM othertable", conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Handle second resultset here
}
}
}
Alternaitvely you might be able to combine your commands up into one batch and instead process multiple resultsets, like this:
using (SqlConnection conn = new SqlConnection())
{
conn.Open()
using (SqlCommand cmd = new SqlCommand("SELECT myrow FROM mytable; SELECT otherrow FROM othertable", conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Handle first resultset here, and then when done call
if (reader.NextResult())
{
// Handle second resultset here
}
}
}
}
When you are processing many resultsets you will find that batching together queries like this can significantly improve performance, however it comes at the price of added complexity in your calling code.
Open only one SQLConnection
Use the keyworkd Using as it will automatically dispose the connection.
If you open connection for each one , it can have performance problems.
Example:
using (SqlConnection con = new SqlConnection(connectionString))
{
//
// Open the SqlConnection.
//
con.Open();
//
// The following code shows how you can use an SqlCommand based on the SqlConnection.
//
using (SqlCommand command = new SqlCommand("SELECT TOP 2 * FROM Dogs1", con))
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("{0} {1} {2}",
reader.GetInt32(0), reader.GetString(1), reader.GetString(2));
}
}
}
One more example:
public DataTable GetData()
{
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection("your connection here")
{
con.Open();
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "your stored procedure here";
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
}
return dt;
}
Purely as an alternative to the using statements:
SqlConnection con = new SqlConnection(myConnectionString);
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = #"SELECT [stuff] FROM [tableOfStuff]";
con.Open();
SqlDataReader dr = null;
try
{
dr = cmd.ExecuteReader();
while(dr.Read())
{
// Populate your business objects/data tables/whatever
}
}
catch(SomeTypeOfException ex){ /* handle exception */ }
// Manually call Dispose()...
if(con != null) con.Dispose();
if(cmd != null) cmd.Dispose();
if(dr != null) dr.Dispose();
The major difference between this and the using statements, is this will allow you to handle exceptions more cleanly.

Categories

Resources