When i analyzed my code from Visual Studio 2013 some warnings appear that "Do not dispose objects multiple times " it also stated that object conn disposed multiple times in object but as i know if i did not use this object multiple times in object than i cant achieve my goals.
so kindly tell me how i can remove this warning ?
here is my code :
private void GetData()
{
DataTable dt = new DataTable();
_connString = ConfigurationManager.AppSettings["connString"];
using (SqlConnection conn = new SqlConnection(_connString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("select * from ref_CourseRegistration_Users", conn);
cmd.CommandType = CommandType.Text;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
conn.Close();
if (ds.Tables[0].Rows.Count > 0)
{
grdUsers.DataSource = ds;
grdUsers.DataBind();
}
}
}
here is screenshot of my analysis :
Here if you are using the using statement
using (SqlConnection conn = new SqlConnection(_connString))
no need to close the connection again
so conn.Close(); is not required.
It'll automatically dispose the object.
When you are opening a connection in using block, the using block will automatically call the Dispose() method while leaving the using block scope.
So, conn.Close(); is not required in your code.
Related
I'm trying to show in my datagridview all the registers from a mariadb database, but when I start the code, it appears the errror "Connection must be valid and open error", the code is Here:
I'll be glad if somebody can help me :)
There are two main problems with your code. Firstly you don't associate your connection object with your command object, instead of
MySqlCommand cmd = new MySqlCommand("SELECT * FROM encomendas");
It should be
MySqlCommand cmd = new MySqlCommand("SELECT * FROM encomendas", bdcon);
Also, there is no need to call cmd.ExecuteNonQuery(). It is also advisable to use using blocks on objects that implement IDisposable to ensure they are disposed of correctly, so your full code might be:
var datatable = new DataTable();
using (var connection = new MySqlConnection("connectionstring"))
using (var command = new MySqlCommand("SELECT * FROM encomendas", connection ))
{
connection.Open()'
using (var reader = command.ExecuteReader())
{
datatable.Load(reader);
}
}
// Bind to your grid view
With that being said, if you are looking to fill a DataTable then MySqlDataAdapater() is the simplest approach:
var dt = new DataTable();
using (var adapter = new MySqlDataAdapter("SELECT * FROM encomendas", "ConnectionString"))
{
adapter.Fill(dt);
}
// Bind to your grid view
Delete MysqlCommand cmd = new MySqlCommand("") row and
try it
using (var sqlCommand = new MySqlCommand("SELECT * FROM encomendas", bdcon))
{
MySqlDataReader read = sqlCommand.ExecuteReader();
dt.Load(read);
}
try it
Your object of MysqlCommand must have association with your object MysqlConnection. Obviously your cmd has no business with bdcon, that is the reason why it says "Connection must be valid and open error" when you call the method ```cmd.ExecuteNonQuery().
Here is a similar snippet.
SqlConnection sqlConnection = new SqlConnection();
SqlCommand cmd = sqlConnection.CreateCommand();
//or
SqlCommand cmd = new SqlCommand("sql text", sqlConnection);
I am really get depressed about this error all function code is correct but still its giving me the error, I am trying to select information from SQL Server database.
Stored procedure:
create procedure sp_select_companydetails
#id varchar(5)
as
begin
select company_name, company_address
from CompanyDetails
end
C# Code:
2) On Form button click event
string id = "1";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_select_companydetails";
cmd.Parameters.Add("#id", id);
FillDataset();
In class
public DataSet FillDataset()
{
try
{
using (cmd)
{
DataSet ds = new DataSet();
cmd.Connection = con;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
cmd.Parameters.Clear();
return ds;
}
}
catch (Exception)
{
throw;
}
}
When I click on form button I get this error:
Procedure or function sp_select_companydetails has too many arguments specified.
Suggest me good solution
Thank you in advance
Instead of using a global SqlCommand, create it as new everytime you need it. This is a recommended approach when you deal with disposable objects
using (SqlConnection con = new SqlConnection(GetConnectionString())
using (SqlCommand myCmd = new SqlCommand("sp_select_companydetails", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#id", SqlDbType.VarChar).Value = "1";
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
return ds;
}
By the way, we cannot see how do you create the SqlConnection, but it seems that you have another disposable object kept at the global level. This is particular nasty with an SqlConnection because this object keeps references to system wide resources both on client and on server. Do not create global connection objects, just create a global method that returns the current connectionstring to use in creation of the local SqlConnection (the GetConnectionString() in my example above). If you think that this is a performance killer I suggest you to read about the concept of connection pooling
I have a code like this in my program and I believe that it's not closing the connection after that the data is getting filled in.
public static string ConnectionInfo = System.Configuration.ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
public static DataTable ExecuteQuery(string query, string table)
{
SqlConnection cnn = new SqlConnection(ConnectionInfo);
SqlDataAdapter Adp = new SqlDataAdapter(query, cnn);
DataSet Ds = new DataSet();
Adp.Fill(Ds, table);
return Ds.Tables[table];
}
Is there any problem in this code ?
The only problem is that you are not using the using statement for the SqlConnection and the DataAdapter. However, DbDataAdapter.Fill opens and closes the connection implicitely.
public static DataTable ExecuteQuery(string query, string table)
{
using(SqlConnection cnn = new SqlConnection(ConnectionInfo))
using(SqlDataAdapter Adp = new SqlDataAdapter(query, cnn))
{
DataTable tbl = new DataTable();
Adp.Fill(tbl);
return tbl;
}
}
The connection object associated with the SELECT statement must be
valid, but it does not need to be open. If the connection is closed
before Fill is called, it is opened to retrieve data, then closed. If
the connection is open before Fill is called, it remains open.
Note that
the using statement will close the connection implicitely even on error
i have used DataAdapter.Fill(DataTable) because you're using a single table anyway
Edit: i've only just noticed that you are using a parameter for the table-name. You can also use DbDataAdapter.Fill(DataSet, String) instead. That does not change anything.
Add a using statement in order to close the connection reliably. This ensures that the connection is closed even if an exception occurs. Change your code as follows:
public static DataTable ExecuteQuery(string query, string table)
{
using(SqlConnection cnn = new SqlConnection(ConnectionInfo))
{
SqlDataAdapter Adp = new SqlDataAdapter(query, cnn);
DataSet Ds = new DataSet();
Adp.Fill(Ds, table);
return Ds.Tables[table];
}
}
Whatever the opening/closing of the connections should be done in try-catch-finally block.
And we should not be using "using"
[using (SqlConnection connection = new SqlConnection(connectionString))]
block. Because if something goes wrong with the network or any exception cause. Connection is not closed. So better to be use try-catch block.
public static DataTable ExecuteQuery(string query, string table)
{
DataSet Ds = new DataSet();
SqlConnection cnn = new SqlConnection(ConnectionInfo);
try{
SqlDataAdapter Adp = new SqlDataAdapter(query, cnn);
Adp.Fill(Ds, table);
return Ds.Tables[table];
}
catch{
throw;
}
finally{
cnn.Close();
}
}
There is already an open DataReader associated with this Command which
must be closed first.
I m facing this issue when same person open the same page at same time on different system.
I have searched a lot on this but found no successful solution.
I have tired :
MultipleActiveResultSets = true in connection string
Increasing Connection waiting time
Verified all connection are closed
This issue comes only when above condition created. Kindly let me know solution which really works
this my connection function which i m using
public DataSet SelectDs(string str)
{
DataSet ds = new DataSet();
if (con.State == ConnectionState.Closed)
{
con.ConnectionString = ConStr;
con.Open();
}
cmd.CommandText = str;
cmd.Connection = con;
cmd.CommandTimeout = 12000;
adpt.SelectCommand = cmd;
adpt.Fill(ds);
con.Close();
return ds;
}
It is a mortal sin to use a global connection object in that way. It is bad (very bad) in WinForms applications, but in ASP.NET is deadly. (as you have discovered)
The usage pattern for a disposable object (and an expensive one like the connection) is
CREATE, OPEN, USE, CLOSE, DESTROY
The Connection Pooling mechanism exist to make easier the usage of this pattern.
Instead you try to work against it and you pay the consequences.
Your code should be rewritten as
public DataSet SelectDs(string str)
{
DataSet ds = new DataSet();
using(SqlConnection con = new SqlConnection(constring)) // CREATE
using(SqlCommand cmd = new SqlCommand(str, con)) // CREATE
{
con.Open(); // OPEN
cmd.CommandTimeout = 12000;
using(SqlAdapter adpt = new SqlAdapter(cmd)) // USE
adpt.Fill(ds);
return ds;
} // CLOSE & DESTROY
}
How about putting inside a Using statement like
using(SqlConnection connection = new SqlConnection("connection string"))
{
connection.Open();
using(SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
} // reader closed and disposed up here
} // command disposed here
} //connection closed and disposed here
in finally clause use this
if (readerObj.IsClosed == false)
{
readerObj.Close();
}
I think you should also dispose your command object before returning dataset.
try cmd.Dispose() after con.close()
I am writing a method that will query a table and return a Dataset object containing the specified column. Moreover, I have a problem with my Username & Password, so I am using Windows authentication for the same but I am not too sure about that in my snippet I have written till now.
protected void GetProgramList()
{
SqlConnection cn = new SqlConnection("server=Daffodils-PC/sqlexpress;Database=Assignment1;Trusted_Connection=Yes;");
SqlCommand cmd = new SqlCommand("SELECT ProgramName FROM Program", cn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet1 ds1 = new DataSet1();
}
I have been trying to follow official MS documentation but I am not sure where I am going? Can someone help me with some links or snippets?
I would say you have 2 options here:
1. to make a DataSet class variable, so its reference can be accessed from all over the class (set its access modifier to public so it can be accessed from other classes)
2. or create a method with its return type of DataSet. But in this case on the other side must be set to receive the DataSet as well:
//2. solution:
private void GetData()
{
//from inside some method:
DataSet ds = GetProgramList();
}
protected DataSet GetProgramList()
{
DataSet ds1 = new DataSet();
using (SqlConnection cn = new SqlConnection("server=Daffodils-PC/sqlexpress;Database=Assignment1;Trusted_Connection=Yes;"))
{
using (SqlDataAdapter da = new SqlDataAdapter(#"SELECT ProgramName FROM Program", cn))
da.Fill(ds1, "TableName1");
}
return ds1;
}
//
//1. solution:
class YourClass
{
DataSet ds1;
protected void GetProgramList()
{
SqlConnection cn = new SqlConnection("server=Daffodils-PC/sqlexpress;Database=Assignment1;Trusted_Connection=Yes;");
SqlCommand cmd = new SqlCommand("SELECT ProgramName FROM Program", cn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
ds1 = new DataSet();
}
}
Place your connection string in AppSettings section in app.config or web.config
public string GetSqlConnection()
{
return System.Configuration.ConfigurationManager.AppSettings["SqlConnectionString"];
}
public DataSet getDataSet(string sql)
{
DataSet ds = new DataSet();
SqlConnection conn = new SqlConnection(GetSqlConnection());
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
da.Fill(ds);
conn.Close();
conn.Dispose();
da.Dispose();
return ds;
}
Suggestion: "use" System.Data and System.Data.SqlClient, and use a "SqlDataReader":
http://www.csharp-station.com/Tutorial/AdoDotNet/lesson04
Either read everything in your routine (generally preferred), or pass the SqlDataReader back to the caller (as a function return).
And be sure to .Close() the reader when you're done :)
SQLDataAdapter basic will get you started with the basics of creating a connection and consuming it in your code.