Reputation: 197
I am trying to fill a dataGridView
with a data from database, it must get the data when the form is loaded & and when a refreshButton
clicked..
here's the code:
public partial class PhoneBookMainWindow : Form
{
static public string connString = "Server=(local); Database=PhoneBook; Trusted_Connection=TRUE";
public SqlConnection connection = new SqlConnection(connString);
private void btnRefreshPhoneBook_Click(object sender, EventArgs e)
{
SqlCommand command = new SqlCommand("SELECT ID, contactName, jobTitle, currentAddress, workAddress, workPhone, cellPhone FROM ContactsInformations", connection);
try
{
SqlDataAdapter dataAdapter = new SqlDataAdapter();
dataAdapter.SelectCommand = command;
DataTable dataSet = new DataTable();
dataAdapter.Fill(dataSet);
BindingSource bindingSrc = new BindingSource();
bindingSrc.DataSource = dataSet;
dataGridView1.DataSource = bindingSrc;
dataAdapter.Update(dataSet);
}
catch (Exception x)
{
MessageBox.Show(x.Message);
throw;
}
}
}
Am using the same code in Form loading
& btn clicking
and they work rightly in the execution, but the problem is appear when i delete a row from database ( using a query by click a delete btn
then click the refresh btn
the exhibition come to my face.
Upvotes: 2
Views: 2922
Reputation: 219027
The issue you seem to be facing is that you have multiple code blocks sharing the same SqlConnection
object. Potential race conditions aside, this means that any one of them may try to dispose of that object before another one has used it.
Once disposed, the object is no longer in a state where you can use it. Specifically in this case, it doesn't have a .ConnectionString
set anymore.
Essentially, this is happening:
Creating a SqlConnection
object isn't a particularly resource-intensive process, so it's best to scope it locally to the code that's going to use it. Something like this:
using (SqlConnection connection = new SqlConnection(connString))
{
using (SqlCommand command = new SqlCommand("SELECT ID, contactName, jobTitle, currentAddress, workAddress, workPhone, cellPhone FROM ContactsInformations", connection))
{
try
{
SqlDataAdapter dataAdapter = new SqlDataAdapter();
dataAdapter.SelectCommand = command;
DataTable dataSet = new DataTable();
dataAdapter.Fill(dataSet);
BindingSource bindingSrc = new BindingSource();
bindingSrc.DataSource = dataSet;
dataGridView1.DataSource = bindingSrc;
dataAdapter.Update(dataSet);
}
catch (Exception x)
{
MessageBox.Show(x.Message);
throw;
}
}
}
I've done two things here:
SqlConnection
object is created inside the method, instead of at the class level. Which means nothing except this method will use it. (So nothing except this method can break it.)using
statements, which is best practice when working with anything that implements IDisposable
.Upvotes: 6