data is not getting deleted from database - c#

In windows desktop application form I am using this code for deleting data from datagridview and database ,I have taken one checkbox column in dataridview ,If I click on checkbox row is getting deleted at that moment from datagridview ,but not from the database therefore when i reload form i can see that row again ,where I am going wrong?
public partial class EditEngClgList : Form
{
private OleDbConnection acccon = null;
private OleDbDataAdapter da = null;
private DataTable dt = null;
private BindingSource bs = null;
private OleDbCommandBuilder cmdb = null;
public EditEngClgList()
{
InitializeComponent();
try
{
acccon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb");
acccon.Open();
}
catch (Exception err)
{
MessageBox.Show("Error:" + err);
}
string sql = "Select * From EngColeges order by EngClgID";
da = new OleDbDataAdapter(sql, acccon);
cmdb = new OleDbCommandBuilder(da);
dt = new DataTable();
da.Fill(dt);
bs = new BindingSource();
bs.DataSource = dt;
dataGridView1.DataSource = bs;
dataGridView1.Columns[1].Visible = false;
dataGridView1.Columns[2].HeaderText = "Engineering College Name";
dataGridView1.Columns[3].HeaderText = "Adress";
dataGridView1.Columns[4].HeaderText = "Entrance Type";
dataGridView1.Columns[2].Width = 400;
}
private void button4_Click(object sender, EventArgs e)
{
List<int> checkedclg = new List<int>();
DataRow dr;
List<int> checkedclgid = new List<int>();
for (int i = 0; i <= dataGridView1.RowCount - 1; i++)
{
if (Convert.ToBoolean(dataGridView1.Rows[i].Cells["Delete"].Value) == true)
{
checkedclg.Add(i);
checkedclgid.Add(Convert.ToInt16(dataGridView1.Rows[i].Cells["Delete"].Value));
}
}
foreach (int k in checkedclg)
{
dr = dt.Rows[k];
dt.Rows[k].Delete();
foreach (int j in checkedclgid)
{
OleDbCommand oleDbCommand = new OleDbCommand("DELETE FROM EngColeges WHERE EngClgID = #clgID", acccon);
oleDbCommand.Parameters.Add("#clgID", OleDbType.Integer).Value = j;
oleDbCommand.Prepare();
oleDbCommand.ExecuteNonQuery();
}
}
}

if (Convert.ToBoolean(dataGridView1.Rows[i].Cells["Delete"].Value) == true)
{
checkedclg.Add(i);
checkedclgid.Add(Convert.ToInt16(dataGridView1.Rows[i].Cells["Delete"].Value));
}
Looks like the wrong cell value is being passed to Convert.ToInt16? It's using the "Deleted" column instead of your ID column.
Also you can delete all the rows in one sql statement using the where in clause, for example:
DELETE FROM table WHERE id IN (1, 2, 3, 4)

Insted of storing value of Delete like this
checkedclgid.Add(Convert.ToInt16(dataGridView1.Rows[i].Cells["Delete"].Value));
storing The values of primary key column like this deletes data properly from database Also
checkedclgid.Add(Convert.ToInt32(dataGridView1.Rows[i].Cells["EngClgID"].Value));

You must change this line:
checkedclgid.Add(Convert.ToInt16(dataGridView1.Rows[i].Cells["Delete"].Value));
to the following:
checkedclgid.Add(Convert.ToInt32(dataGridView1.Rows[i].Cells["CellInTheInvisible‌​Column"].Value));
Because you're converted a boolean type to Int16 and then you're used it in your query for checking with ID in your related table.
OleDbCommand oleDbCommand = new OleDbCommand("DELETE FROM EngColeges WHERE EngClgID = #clgID", acccon);
So, you must store ID of rows that you want to delete them.

I think first of all you are deleting the row and then you are attempting to delete it from database. First of all you delete the row from database and then again call the select query for that table.

All you have right now is a command. You need your OleDbDataAdapter, and pass the command to it:
...
da = new OleDbDataAdapter(sql, acccon);
da.DeleteCommand = oleDbCommand;
More Info: http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbdataadapter.deletecommand.aspx

Just replace these two lines:
oleDbCommand.Prepare();
oleDbCommand.ExecuteNonQuery();
With:
da.DeleteCommand = oleDbCommand;
References:
http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbdataadapter.deletecommand.aspx

Related

DataGridView add column by code

I need to add columns to my DataGridView dynamically... to do this here is my code:
dgv.Columns.Clear();
dgv.AutoGenerateColumns = false;
for (int i = 0; i < fields.Length; i++)
{
var newColumn = new DataGridViewColumn(new DataGridViewTextBoxCell());
newColumn.Name = fields[i];
newColumn.DataPropertyName = fields[i];
newColumn.HeaderText = fields[i];
dgv.Columns.Add(newColumn);
}
And after, when I link my query to the DataSource I retrieve this error:
The value can't be null.
Parameter name: columnName
And the strange thing is that here is my DataGridView/DataTable situation:
The names seems right...
The other strange thing is that the first row is shown, but the others gives the exception (the query is OK and the data are valid...)
here is the code to create the DataSource for the table:
public DataTable getData()
{
DataSet ds = new DataSet();
SqlCommand cmd = new SqlCommand(item.Query, db.getConnection());
SqlDataAdapter dap = new SqlDataAdapter();
dap.SelectCommand = cmd;
dap.Fill(ds);
return ds.Tables[0];
}
and after:
dgv.DataSource = getData();

How do I sort a dataGridView the was populated with SqlDataReader and BindingSource , when i push a button

I am trying to create a sort button , to sort the all ready filtered Data that is in datagridview.
But when i do :
private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedItem != null)
{
if (sortComboBox.SelectedItem == "Price low - high")
{
this.dataGridView1.Sort(this.dataGridView1.Columns["Price"], ListSortDirection.Ascending);
}
if (sortComboBox.SelectedItem == "Price high - low")
{
this.dataGridView1.Sort(this.dataGridView1.Columns["Price"], ListSortDirection.Descending);
}
}
else
{
MessageBox.Show("Please select a component");
}
}
Then it Give me an error:
DataGridView control cannot be sorted if it is bound to an IBindingList that does not support sorting.
This is how I populated the dataGridView :
command = new SqlCommand("SELECT [Price],[Mark],[Type],[Code],[Series],[Rating],[Description],[Comments]FROM "+database+" ORDER BY CAST(ID AS INT) ", connection);
SqlDataReader reader = command.ExecuteReader();
// Create a BindingSource object
BindingSource bs = new BindingSource();
// Assign the reader to the binding source
bs.DataSource = reader;
// Assign the BindingSource to the DataGridView DataSource
dataGridView1.DataSource = bs;
reader.Close();
Please help me to show how sort the Data the user have in the dataGridView currently.
P.S. the allowusertoordercolumns is also not working.
I have this but its not working
List<string[]> allDatalist = new List<string[]>();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
string[] rowData = new string[8]; // 8 because you're loading from a table with 8 columns
for (var i = 0; i < rowData.Length; i++)
{
MessageBox.Show(reader.GetString(i));
rowData[i] = reader.GetString(i);
}
allDatalist.Add(rowData);
}
for (var x = 0; x < allDatalist.Count; x++)
{
dataGridView1.Rows.Add(allDatalist[x]);
}
}
reader.Close();
}
So this is merely pseudo-code, but I'm sure you get the idea:
First load everything into a list:
var command = new SqlCommand("SELECT [Price],[Mark],[Type],[Code],[Series],[Rating],[Description],[Comments]FROM "+database+" ORDER BY CAST(ID AS INT) ", connection);
List<object[]> allData = new List<object[]>();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
object[] rowData = new object[8]; // 8 because you're loading from a table with 8 columns
for (var i = 0; i < rowData.Length; i++)
{
rowData[i] = reader.GetObject(i);
}
allData.Add(rowData);
}
}
// Congratulations, you now have a collection containing all the data from your database.
// At this point, you'll want to sort on one of the column (Loop through every row in the allData list, and compare position 0 or 1 or whatever data you want.
Hope this answers your question.
At the end of the day this was all I wanted..
SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd, connectionString);
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
DataSet ds = new DataSet();
dataAdapter.Fill(ds);
dataGridView1.ReadOnly = true;
dataGridView1.DataSource = ds.Tables[0];
Now It can be sorted with headers of datagrid.

Retrieving selected checkedlistbox

I'm still learning C# and winform and I can't seem to find a fix to my problem. The problem is whenever I select items in my sql generated checkedlistbox and press the button2 event it won't show the actual data, it just shows "System.Data.DataRowView" am I missing something here is the code..
private void button2_Click(object sender, EventArgs e)
{
int counter = checkedListBox1.SelectedItems.Count;
List<string> selecteditems = new List<string>();
for (int i = 0; i < counter; i++)
{
selecteditems.Add(checkedListBox1.SelectedItems[i].ToString());
}
MessageBox.Show(selecteditems[0]);
for the generation of checkedlistbox here is the code.
con.Open();
SqlCommand cmd = new SqlCommand("Select * from tbl_members ORDER BY Position", con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
SqlDataReader reader = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Columns.Add("FullName", typeof(string));
dt.Load(reader);
DataSet ds = new DataSet();
adapter.Fill(ds);
checkedListBox1.DataSource = ds.Tables[0];
checkedListBox1.DisplayMember = "FullName";
checkedListBox1.ValueMember = "FullName";
checkedListBox1.Enabled = true;
checkedListBox1.Refresh();
count = Convert.ToInt32(numericUpDown1.Value);
con.Close();
Try replace your for loop in button2_Click to this:
foreach (DataRowView rowView in checkedListBox1.CheckedItems)
{
selecteditems.Add(rowView["FullName"].ToString());
}
there is both
MessageBox.Show(checkedListBox1.CheckedItems[0].ToString());
and
MessageBox.Show(checkedListBox1.SelectedItems[0].ToString());
use them according to your need I think you were looking for first one
Try using Convert.ToString(checkedListBox1.SelectedItems[i]) instead of .ToString()
.ToString() generally returns variable's class name in string if `.ToString()' not overrided by class.

Populate Combobox with Access Table Names

I have a datatable that I am able to populate from my access database without a problem but I want to add a step in it:
private void button_Open_Click(object sender, EventArgs e)
{
var open = new OpenFileDialog
{
InitialDirectory = "c:\\",
Filter = #"Access Files (*.mdb)|*.mdb|All files (*.*)|*.*",
FilterIndex = 0,
RestoreDirectory = true,
Multiselect = false
};
open.ShowDialog();
if (string.IsNullOrEmpty(open.FileName)) return;
try
{
var con = new OleDbConnection();
con.ConnectionString = "Provider= microsoft.jet.oledb.4.0; data source = " + open.FileName;
con.Open();
var dt = new DataTable();
var da = new OleDbDataAdapter("select * from tblCustomerAccount", con);
da.Fill(dt);
dataGridView_AccessDatabase.DataSource = dt.DefaultView;
con.Close();
}
catch (OleDbException ex)
{
//get the error message if connection failed
MessageBox.Show("Error in connection ..." + ex.Message);
}
}
I'd like to add in there a combobox that is populated with the table names then, off the selection of the combobox, the datatable is populated.
How do I populate the combobox with the table names?
Thanks!
//
string[] restrictions = new string[4];
restrictions[3] = "Table";
con.Open();
DataTable tabls=con.GetSchema("Tables",restrictions);
return a datatable that a column of that represent table names
you can bind this datatable to combobox and set datamemebr to TABLE_NAME

Data does not display when making loop statement in datagridview control

I had datagridview control which retrieves data from database. I had my code to do that, but no data apeared in gridview. I made a break point in the loop but when on DataGridViewTextBoxCell Number = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
datagrid view apeared with no data
private void getcategory()
{
for (int i = 0; i < DGCategory.Rows.Count; i++)
{
for (int l = 0; l < DGCategory.Rows[i].Cells.Count; l++)
{
DataGridViewTextBoxCell Number = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
DataGridViewTextBoxCell Category = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
DataGridViewTextBoxCell Parent = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
DataGridViewCheckBoxCell Active = (DataGridViewCheckBoxCell)DGCategory.Rows[i].Cells[l];
DataGridViewTextBoxCell AddDate = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
using (SqlConnection Con = GetConnection())
{
SqlCommand cmd = new SqlCommand("SP_GetAllCategories", Con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader dr;
dr = cmd.ExecuteReader();
if (dr.Read())
{
Number.Value = dr["Number"].ToString();
Category.Value = dr["Category"].ToString();
Parent.Value = dr["Parent"].ToString();
Active.Value = dr["Active"].ToString();
AddDate.Value = dr["AddDate"].ToString();
}
}
}
}
}
If u want to get values from your database into a grid view .. use the following:
write your query in a String called "selectCommand" for example then use a dataset to get the results:
public DataSet GetSearchEmpResults(string emp_fn)
{
string selectCommand = #"select
emp.first_name as 'First Name',
emp.last_name as 'Last Name'
from Employees emp
where emp.first_name = '" + emp_fn + "';";
SqlCommand command = new SqlCommand(selectCommand, this.Connection);
DataSet ds = new DataSet("Results");
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(ds, "Results");
return ds;
}
then in the data gridview code:
DataSet results = db.GetSearchEmpResults(fristName, lastName); //this depends on your results
dataGridViewResults.DataSource = results;
dataGridViewResults.DataMember = "Results";
the dataGridViewResults is the name of the data gridview you want your results yo appear in.
Note that you should provide the connection to your database in order to receive the results.

Categories