I run a standard query against a DB2 database with C# ADO.NET OleDb and using statements and get
System.Data.OleDb.OleDbException (0x80004005): CLI0115E Invalid cursor state. SQLSTATE=24000
When I include the dispose methods for each OleDb object, the query runs.
Why does this fail without the Dispose methods? From everything i have researched the using statements should dispose of the objects for me. I am using .NET 4.5.1
using (OleDbConnection conn = DBConn.BIPSConn)
{
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
using (OleDbDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
string orderNumber = rdr.GetString(0).Trim();
string originCode = rdr.GetString(1).Trim();
string destinationCode = rdr.GetString(3).Trim();
Record record = new Record(orderNumber, originCode, destinationCode);
RecordList.Add(record);
}
// for unknown reasons, without these dispose methods we get an Invalid Cursor State error
rdr.Dispose();
}
cmd.Dispose();
}
conn.Dispose();
}
You have a using block -- you don't want to call Dispose() you want to call Close(). The using block will take care of the dispose. Add in a call to Close instead.
Related
I've got a question. Could you tell me what could be wrong in this code? So case looks like this: program shows me this error but not every time.Sometimes it does show it some times it doesn't.
Error:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.dll
Additional information: There is already an open DataReader associated with this Command which must be closed first.
Code:
private void loadlist()
{
ItemList.Items.Clear();
NumberList.Items.Clear();
newConnection.connection();
cmd.CommandText = "select * from Items";
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
ItemList.Items.Add(dr[0].ToString());
NumberList.Items.Add(dr[1].ToString());
}
}
dr.Close();
newConnection.cnOff();
}
I can delete "dr.Close()" and it worked and after i try run and i must edit some code(write back "dr.Close()" ) and it worked back. Btw. sorry for my english :<
Use a local SqlDataReader instance for your method. Also, If you use a using block, It will take care of calling the Dispose method and cleaning up the memory.
using(SqlDataReader dr= cmd.ExecuteReader())
{
while (dr.Read())
{
//read from reader now
ItemList.Items.Add(dr[0].ToString());
}
}
You may use the using block on your connection and command objects as well.
var connStr = "ReplaceYourConnectionStringHere"
using (var c = new SqlConnection(connStr))
{
using (var cmd = new SqlCommand("SELECT * FROM ITEMS",c))
{
c.Open();
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
//read from reader now
//ItemList.Items.Add(dr[0].ToString());
}
}
}
//No need to explicitly close connection :) Thanks to "using"
}
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object
I have the following set of code:
using (OracleConnection conn = new OracleConnection(m_fceConn))
{
conn.Open();
using (OracleCommand cmd = new OracleCommand(m_sql, conn))
{
using (OracleDataReader reader = cmd.ExecuteReader())
{
reader.Read();
}
}
conn.Close();
}
Is there a better way to format this? Granted, later on I will probably be breaking out opening a connection, running a query, and closing the connection into separate functions at a later date but this nesting will still be there "behind the scenes" so to speak.
I read on another thread that I could format things like so:
using (OracleConnection conn = new OracleConnection(m_fceConn))
using (OracleCommand cmd = new OracleCommand(m_sql, conn))
But considering that I have code in between each of these statements I don't believe that I can omit the brackets like that. I'm just looking for the best/safest practice here since I'm still realtively new/noob to C#. Thanks.
I could be wrong, but I don't think you need to open the connection before passing it to OracleCommand. You just have to open it prior to executing a command. So you could write the above as:
using (OracleConnection conn = new OracleConnection(m_fceConn))
using (OracleCommand cmd = new OracleCommand(m_sql, conn))
{
conn.Open();
using (OracleDataReader reader = cmd.ExecuteReader())
{
reader.Read();
}
}
(you also shouldn't need to explicitly close either since disposing of the connection should close it automatically).
There's nothing special about the above code (other than it looks nice), it's just using normal C# rules that apply single commands to such blocks. it's the same as this:
if (...)
if (...)
dosomething(); // Look Ma, no curly braces
it's just that you're "stacking" multiple single statements.
What you have is properly formatted, though it's not necessary to call conn.Close() since the connection will be disposed (and thus closed) at the end of the using block that declared it.
You can, however, omit the brackets for the second statement, since the entirety of that statement is just another using block.
Your first using statement needs to have brackets, since you have the conn.Open() call there. The second and third can be stacked as you stated, which is pretty idiomatic C# (and preferred, in my case).
using (OracleConnection conn = new OracleConnection(m_fceConn))
{
conn.Open();
using (OracleDataReader reader = new OracleCommand(m_sql, conn).ExecuteReader())
{
reader.Read();
}
conn.Close();
}
EDIT
On second thought, don't do this. It wouldn't dispose of the command object. I will leave the answer here as an example of what NOT to do.
I have a piece of code to execute a mysqlcommand but sometimes it throws the exception
There is already an open DataReader associated with this Connection which must be closed first
It is unpredictable when the exception will be throw sometimes my program works fine for over 15min but then it craches. I looked online for an answer but i didn't find anything.
This is my code:
public static List<string> DoCommand(string commandLine, string myConString) {
MySqlCommand command = new MySqlCommand(commandLine);
List<string> tables = new List<string>();
try {
using (MySqlConnection mySqlConnection = new MySqlConnection(myConString)) {
mySqlConnection.Open();
command.Connection = mySqlConnection;
command.BeginExecuteReader();
using (MySqlDataReader SqlDR = command.ExecuteReader()) {
while (SqlDR.Read()) { //Async reading, wait untill reading is done
tables.Add(SqlDR.GetString(0));
}
//SqlDR.Close();
//SqlDR.Dispose();
}
//mySqlConnection.Close();
//mySqlConnection.Dispose();
}
} catch (Exception exp) { } finally {
command.Connection = null;
}
//System.Threading.Thread.Sleep(50); //Give connection time to flush
return tables;
}
there are some of the solutions that didn't work in comment.
This is the only code taht connects to mysql so i am sure all connections are closed
If you above code is what you intended, this line is not required:
command.BeginExecuteReader();
The SqlCommand.BeginExecuteReader Method:
Initiates the asynchronous execution
of the Transact-SQL statement or
stored procedure that is described by
this SqlCommand, and retrieves one or
more result sets from the server
Replace
using (MySqlDataReader SqlDR = command.ExecuteReader())
with
using (MySqlDataReader SqlDR = command.EndExecuteReader()
I have an application that fires a mysql command (query) "show databases", the query works and returns properly but I can't close my connections. The user I used had 24 connections allowed at the same time so the problem popped up further down my program but reducing the allowed connections to 2 shows me that I can't even close the first query (which isn't in a loop). The code is the following:
protected override Dictionary<string, Jerow_class_generator.Database> loadDatabases()
{
MySqlConnection sqlCon = new MySqlConnection(this.ConnectionString);
sqlCon.Open();
MySqlCommand sqlCom = new MySqlCommand();
sqlCom.Connection = sqlCon;
sqlCom.CommandType = CommandType.Text;
sqlCom.CommandText = "show databases;";
MySqlDataReader sqlDR;
sqlDR = sqlCom.ExecuteReader();
Dictionary<string, Jerow_class_generator.Database> databases = new Dictionary<string, Jerow_class_generator.Database>();
string[] systemDatabases = new string[] { "information_schema", "mysql" };
while (sqlDR.Read())
{
string dbName = sqlDR.GetString(0);
if (!systemDatabases.Contains(dbName))
{
databases.Add(sqlDR.GetString(0), new MySQL.Database(dbName, this));
}
}
sqlCom.Dispose();
sqlDR.Close();
sqlCon.Close();
sqlCon.Dispose();
return databases;
}
P.S. The 'New MySQL.Database(dbName, this));' is my owm made class which only stores the DB structure, could be considered irrelevant.
The exact error I get is 'max_user_connections'. on the connection.open line of the next time a query needs to be fired.
Rather than keeping track of all the Open/Close/Dispose calls all over the place, I'd recommend just replacing all of those with using statements. This will make sure the expected scope of each object is clear and that it will be destroyed/disposed upon exiting that scope.
Close() nor using will help alone with your problem because ADO.NET is using its own connection pooling and connections are by default not closed until program is closed. There are few options to solve this, but consider performance implications and is this really desired behavior for your application.
Add ";Pooling=False" to your connection string.
SqlConnection.ClearPool Method
SqlConnection.ClearAllPools Method
For more information read: SQL Server Connection Pooling (ADO.NET)
Along with the using suggestions above, when creating your sqlDR variable you should use the CloseConnection command behavior to close the actual connection if that is your intended action. As noted in the documentation here.
When the command is executed, the associated Connection object is closed when the associated DataReader object is closed.
So your code to instantiate your reader would look like this:
//to instantiate your variable
MySqlDataReader sqlDR;
sqlDR = sqlCom.ExecuteReader(CommandBehavior.CloseConnection);
//closing your datareader reference here will close the connection as well
sqlDR.Close();
If you wrap all your code in a using block using the above method, you don't need any of those Close() or Dispose() methods other than the sqlDR.Close();
when use "using" key word what happen is.when the garbage collector activate it first dispose objects which was declred in using statement.
I recommend using connection pooling in combination with the MySqlHelper class, passing the connection string as the first argument. That allows MySQL to open the connection if necessary, or keep it open according to the pooling cfg, without you having to know about it.
I changed my code to use 1 connection and keep it open and when testing I came across an error that a datareader should be closed. Now since all my queries didn't close the dataReader object (I used dataTable.Load(cmd.ExecuteReader()).) I think the problem might be there.
Keeping 1 open connection worked perfectly so I don't know what caused the not closing problem. I gues it was the dataReader not closing by itself.
Close() will definitely help you close your.
using (MySqlConnection conn = GetConnection())
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "UserDetail";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
list.Add(new Album()
{
Id = Convert.ToInt32(reader["UId"]),
Name = reader["FirstName"].ToString(),
ArtistName = reader["LastName"].ToString()
});
}
}
}
}
In the above code, you can see one if condition before opening the connection it will help you to reuse your already open connections check below code.
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
I have two questions.
1) Should you always use a using statement on a connection? So, I would use it on the connection and then another one on a reader within the connection? So I would be using two using statements.
2) Lets say you use the using statement on the connection and also a reader being returned on the connection. So you have two using statements. Does it create two Try{}Finally{} blocks or just one?
Thanks!
Be careful here. You should always have a using statement on any local object that implements IDisposable. That includes not only connections and readers, but also the command. But it can be tricky sometimes exactly where that using statement goes. If you're not careful it can cause problems. For example, in the code that follows the using statement will close your reader before you ever get to use it:
DataReader MyQuery()
{
string sql="some query";
using (var cn = new SqlConnection("connection string"))
using (var cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
return rdr;
}
}
}
Instead, you have four options. One is to wait to create the using block until you call the function:
DataReader MyQuery()
{
string sql="some query";
using (var cn = new SqlConnection("connection string"))
using (var cmd = new SqlCommand(sql, cn))
{
cn.Open();
return cmd.ExecuteReader();
}
}
using (var rdr = MyQuery())
{
while (rdr.Read())
{
//...
}
}
Of course, you still have to careful with your connection there and it means remember to write a using block everywhere you use the function.
Option two is just process the query results in the method itself, but that breaks separation of your data layer from the rest of the program. A third option is for your MyQuery() function to accept an argument of type Action that you can call inside the while (rdr.Read()) loop, but that's just awkward.
I generally prefer option four: turn the data reader into an IEnumerable, like this:
IEnumerable<IDataRecord> MyQuery()
{
string sql="some query";
using (var cn = new SqlConnection("connection string"))
using (var cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
yield return rdr;
}
}
}
Now everything will be closed correctly, and the code that handles it is all in one place. You also get a nice bonus: your query results will work well with any of the linq operators.
Finally, something new I'm playing with for the next time I get to build a completely new project that combines the IEnumerable with passing in a delegate argument:
//part of the data layer
private static IEnumerable<IDataRecord> Retrieve(string sql, Action<SqlParameterCollection> addParameters)
{
//DL.ConnectionString is a private static property in the data layer
// depending on the project needs, it can be implementing to read from a config file or elsewhere
using (var cn = new SqlConnection(DL.ConnectionString))
using (var cmd = new SqlCommand(sql, cn))
{
addParameters(cmd.Parameters);
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
yield return rdr;
}
}
}
And then I'll use it within the data layer like this:
public IEnumerable<IDataRecord> GetFooChildrenByParentID(int ParentID)
{
//I could easily use a stored procedure name instead, and provide overloads for commandtypes.
return Retrieve(
"SELECT c.*
FROM [ParentTable] p
INNER JOIN [ChildTable] c ON c.ParentID = f.ID
WHERE f.ID= #ParentID", p =>
{
p.Add("#ParentID", SqlDbType.Int).Value = ParentID;
}
);
}
1) Should you always use a using
statement on a connection? So, I would
use it on the connection and then
another one on a reader within the
connection? So I would be using two
using statements.
Yes, because they implement IDisposable. And don't forget a using statement on the command too :
using (DbConnection connection = GetConnection())
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT FOO, BAR FROM BAZ";
connection.Open();
using (DbDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
....
}
}
}
2) Lets say you use the using
statement on the connection and also a
reader being returned on the
connection. So you have two using
statements. Does it create two
Try{}Finally{} blocks or just one?
Each using statement will create its own try/finally block
You should always use a using statement when an object implements IDisposable. This includes connections.
It will create two nested try{}finally{} blocks.
Special point on 1). You need to specifically avoid that technique when the connection is used in asynchronous ADO.NET methods - like BeginExecuteReader, because more than likely, you will fall out of scope and try to dispose the connection while the async operation is still in progress. This is similar to the case when you are using class variables and not local variables. Often times the connection reference is stored in a class used as the "control block" for the asynchronous operation.
To answer each one:
1) Yes, this would be best practice to dispose both as soon as possible.
2) using() will create two blocks, wrapped in each other in the same order. It will dispose the inner object (the reader) first, then dispose the object from the outer using (the connection).
Probably this article will be interesting for you: How to Implement IDisposable and Finalizers: 3 Easy Rules