I'm Experimenting with databases and I'm finding different methods to optimize my codes. Here I'm using a different class to stop re writing the same codes such as for add, Delete and update we use the same ExecuteNonQuery() method. So far Update delete methods worked well except the Insert. Compiler doesn't give any errors but the values taken from the text boxes doesn't go to the variable string query. I'm new to c# coding. Can anyone help me? or an advice?
using DBconnectionExercise.DBConnection_Components;
namespace DBconnectionExercise
{
public partial class Student_Form : Form
{
DBComps dc = new DBComps();
//public string constring;
//public SqlConnection con = null;
//public SqlCommand com = null;
public String query;
public Student_Form()
{
InitializeComponent();
//constring = "Data Source=ASHANE-PC\\ASHANESQL;Initial Catalog=SchoolDB;Integrated Security=True";
//con = new SqlConnection(constring);
dc.ConnectDB();
}
private void Form1_Load(object sender, EventArgs e)
{
loadGridData();
}
private void dtp_dob_ValueChanged(object sender, EventArgs e)
{
DateTime Now = DateTime.Today;
DateTime Dob = dtp_dob.Value.Date;
int a = Now.Year - Dob.Year;
if (Now < Dob.AddYears(a)) a--;
tb_Age.Text = a.ToString();
}
private void loadGridData()
{
try
{
query = "Select * from tb_Student";
//dc.OpenCon();
//SqlDataAdapter da = new SqlDataAdapter(query, con);
DataTable dt1 = new DataTable();
dt1 = dc.Data_Table(query);
//da.Fill(dt);
Stu_DataGrid.DataSource = dt1;
//con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void ClearData()
{
tb_Name.Clear();
tb_Address.Clear();
tb_Telno.Clear();
tb_Search.Clear();
tb_Age.Clear();
dtp_dob.Value = DateTime.Today;
}
private void btn_Add_Click(object sender, EventArgs e)
{
try
{
String name = tb_Name.Text;
DateTime dob = dtp_dob.Value.Date;
int age = Convert.ToInt32(tb_Age.Text);
String Address = tb_Address.Text;
int telno = Convert.ToInt32(tb_Telno.Text);
int line = 0;
//con.Open();
query = "Insert into tb_Student values(#Stu_Name, #Stu_DOB, #Age, #Stu_Address, #Stu_Tel_no)";
//query = "Insert into tb_Student (Stu_Name, Stu_DOB, Age, Stu_Address, Stu_Tel_no) Values('" + name + "','" + dob + "','" + age + "','" + Address + "','" + telno + "')";
MessageBox.Show(query);
//com = new SqlCommand(query, con);
// This is the Insert/save code
DBComps.com.Parameters.AddWithValue("#Stu_Name", name);
DBComps.com.Parameters.AddWithValue("#Stu_DOB", dob);
DBComps.com.Parameters.AddWithValue("#Age", age);
DBComps.com.Parameters.AddWithValue("#Stu_Address", Address);
DBComps.com.Parameters.AddWithValue("#Stu_Tel_no", telno);
//line = com.ExecuteNonQuery();
line = dc.ExeNonQuery(query);
//com.Dispose();
//con.Close();
if (line > 0)
{
loadGridData();
ClearData();
MessageBox.Show("Data saved sucessfully!", "Data Saved", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
MessageBox.Show("Data not Saved", "Error Save", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
This is the DBComps class which I used to write the Sql Function methods.
namespace DBconnectionExercise.DBConnection_Components
{
public class DBComps
{
public String conSring;
public SqlConnection con = null;
public static SqlCommand com = null;
public void ConnectDB()
{
conSring = "Data Source=ASHANE-PC\\ASHANESQL;Initial Catalog=SchoolDB;Integrated Security=True";
con = new SqlConnection(conSring);
}
public void OpenCon()
{
con.Open();
}
public void CloseCon()
{
con.Close();
}
public int ExeNonQuery(String query) //the method for Insert, update and delete.
{
int line = 0;
OpenCon();
com = new SqlCommand(query, con);
line = com.ExecuteNonQuery();
com.Dispose();
CloseCon();
return line;
}
}
}
This is really really bad way of talking to database, its hackable using SQL injection and since you are learning, its right time to point this out:
query = "Insert into tb_Student values('"+ name +"','"+ dob +"','"+ age +"','"+ Address +"','"+ telno +"')";
read up on sql injection as to why and how, and look for best practices to find out better ways .
OK finally I came up with the Answer to my question as I expected. Here how to do this;
private void btn_Add_Click(object sender, EventArgs e)
{
try
{
String name = tb_Name.Text;
DateTime dob = dtp_dob.Value.Date;
int age = Convert.ToInt32(tb_Age.Text);
String Address = tb_Address.Text;
int telno = Convert.ToInt32(tb_Telno.Text);
int line = 0;
query = "Insert into tb_Student values('"+ name +"','"+ dob +"','"+ age +"','"+ Address +"','"+ telno +"')";
MessageBox.Show(query); //To see it works!
line = dc.ExeNonQuery(query);
if (line > 0)
{
loadGridData();
ClearData();
MessageBox.Show("Data saved sucessfully!", "Data Saved", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
MessageBox.Show("Data not Saved", "Error Save", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Always remember to write the query statement variables/values exactly as to coincide with the table headers. Otherwise it will generate errors. Thanks everyone for helping with this question! :-)
Related
Trying to update the first name of the student there is a textbox "FirstNameTextbox" information was loaded to it from the DB, when I change the information in the textbox and try to write the changes it read only the original data.So if it loaded "Craig" as the first name from the DB, i would edit and put "Chris" in the textbox, what happens is that Craig is written to the DB and not "Chris"
int stuID = getSqlStuID(IDNUMLabel.Text);
SqlConnection conn = new SqlConnection(GetConnectionString());
string sqlUpdateStudent = "Update tblStudent set fname = #fname where stuID = #stuID";
SqlCommand cmd = new SqlCommand(sqlUpdateStudent, conn);
conn.Open();
cmd.Parameters.AddWithValue("#stuID", stuID);
cmd.Parameters.AddWithValue("#fname", FirstNameTextbox.Text);
cmd.ExecuteNonQuery();
ErrorMessage.Text = "Success";
protected void Page_Load(object sender, EventArgs e)
{
if (Session["User"] != null)
{
IDNUMLabel.Text = Session["User"].ToString();
getStuData(Session["User"].ToString());
}
else
{
Response.Redirect("../Login/Login.aspx");
}
}
private void getStuData(string id)
{
SqlConnection conn = new SqlConnection(GetConnectionString());
string sql = "Select fname, sname From tblStudent Where idnumber = '" + id + "' ";
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
conn.Open();
SqlDataReader selectedRecord = cmd.ExecuteReader();
cmd.CommandType = CommandType.Text;
while (selectedRecord.Read())
{
FirstNameTextbox.Text = selectedRecord["fname"].ToString();
LastNameTextbox.Text = selectedRecord["sname"].ToString();
}
selectedRecord.Close();
}
catch (System.Data.SqlClient.SqlException ex)
{
//id = 0;
//string msg = "Error reading Student ID";
//msg += ex.Message;
//throw new Exception(msg);
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
At what point do you make the actual update? After a button was pressed, after the value was entered on the textbox...? You're missing the method in which the code that handles the update is placed...
Maybe this could help: How to display data from database into textbox, and update it
I made a project using c# and data base using access accdb and connected between them both. I made 2 buttons, first one to add new costumer, which works perfectly, and second one to update the data of the costumer (first name and last name), for some reason, the update button does not work, there is no error when I run the project, but after I click nothing happens...
private void button2_Click(object sender, EventArgs e)
{
connect.Open();
string cid = textBox1.Text;
string cfname = textBox2.Text;
string clname = textBox3.Text;
OleDbCommand command = new OleDbCommand();
command.Connection = connect;
command.CommandText = "UPDATE Tcostumers SET cfname= " + cfname + "clname= " + clname + " WHERE cid = " + cid;
if (connect.State == ConnectionState.Open)
{
try
{
command.ExecuteNonQuery();
MessageBox.Show("DATA UPDATED");
connect.Close();
}
catch (Exception expe)
{
MessageBox.Show(expe.Source);
connect.Close();
}
}
else
{
MessageBox.Show("ERROR");
}
}
I believe your commandtext is where the trouble lies;
command.CommandText = "UPDATE Tcostumers SET cfname= " + cfname + "clname= " + clname + " WHERE cid = " + cid;
You require a comma between the set statements, and also as Gino pointed out the speechmarks.
Edit:
It's better than you use parameters for your variables, your current method is open to SQL injection, eg.
private void button2_Click(object sender, EventArgs e)
{
OleDbCommand command = new OleDbCommand(#"UPDATE Tcostumers
SET cfname = #CFName,
clname = #CLName
WHERE cid = #CID", connect);
command.Parameters.AddWithValue("#CFName", textBox2.Text);
command.Parameters.AddWithValue("#CLName", textBox3.Text);
command.Parameters.AddWithValue("#CID", textBox1.Text);
try
{
connect.Open();
}
catch (Exception expe)
{
MessageBox.Show(expe.Source);
}
try
{
command.ExecuteNonQuery();
MessageBox.Show("DATA UPDATED");
}
catch (Exception expe)
{
MessageBox.Show(expe.Source);
}
finally
{
connect.Close();
}
}
Its how I tend to format my code, so do as you will with it. Hope it helps.
It might be a stupid thing but...
you're updating strings not ints so try adding '' to your strings something like:
command.CommandText = "UPDATE Tcostumers SET cfname= '" + cfname + "' clname='" + clname + "' WHERE cid = " + cid;
//my sample code for edit/update
Table Name = StudentFIle
Fields = id,fname,lname
bool found = false;
OleDbConnection BOMHConnection = new OleDbConnection(connect);
string sql = "SELECT * FROM StudentFIle";
BOMHConnection.Open();
OleDbCommand mrNoCommand = new OleDbCommand(sql, BOMHConnection);
OleDbDataReader mrNoReader = mrNoCommand.ExecuteReader();
while (mrNoReader.Read())
{
if (mrNoReader["id"].ToString().ToUpper().Trim() == idtextbox.Text.Trim())
{
mrNoReader.Close();
string query = "UPDATE StudentFIle set fname='" +firstnametextbox.Text+ "',lname='"+lastnametextbox.Text+"' where id="+idtextbox.Text+" ";
mrNoCommand.CommandText = query;
mrNoCommand.ExecuteNonQuery();
MessageBox.Show("Successfully Updated");
found = true;
break;
}
continue;
}
if (found == false)
{
MessageBox.Show("Id Doesn't Exist !.. ");
mrNoReader.Close();
BOMHConnection.Close();
idtextbox.Focus();
}
I have this basic WinForms application user interface:
And I want to add the data both to the DataGridView and the sql table, when the "Gem" button is clicked. I have this following code:
private void Form2_Load(object sender, EventArgs e)
{
try
{
con = new SqlConnection();
con.ConnectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Produkt.mdf;Integrated Security=True";
con.Open();
//adap = new SqlDataAdapter("select SN, FName as 'Navn', MName as 'Vare nr', LName as 'Antal', Age from Produkt", con);
string sql = "SELECT Navn, Varenr, Antal, Enhed, Priseksklmoms, Konto FROM ProduktTable";
adap = new SqlDataAdapter(sql, con);
ds = new System.Data.DataSet();
adap.Fill(ds, "ProduktTable");
dataGridView1.DataSource = ds.Tables["ProduktTable"];
}
catch (Exception ex)
{
MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void button1_Click(object sender, EventArgs e)
{
string navn = textBox2.Text;
int varenr = int.Parse(textBox3.Text);
float antal = (float)Convert.ToDouble(textBox4.Text);
string enhed = textBox5.Text;
string konto = comboBox2.Text;
float pris = (float)Convert.ToDouble(textBox6.Text);
dataGridView1.Rows[0].Cells[0].Value = navn;
dataGridView1.Rows[0].Cells[1].Value = varenr;
string StrQuery;
try
{
SqlCommand comm = new SqlCommand();
comm.Connection = con;
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
StrQuery = #"INSERT INTO tableName ProduktTable ("
+ dataGridView1.Rows[i].Cells["Varenr"].Value + ", "
+ dataGridView1.Rows[i].Cells["Antal"].Value + ");";
comm.CommandText = StrQuery;
comm.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
This is just an example with the purpose for storing the string "navn" and the integer "Varenr" in the DataGridView and the sql. When Im running the application and clicking on the button, following error occurs:
What's wrong with the procedure ?.
Thanks in advance
The format for an insert name doesn't require the words tableName. It wants the actual table name.
INSERT INTO tableName ProduktTable
should be
INSERT INTO ProduktTable
assuming Produ**K**tTable isn't a typo.
I've made a library management system. Put 4 boxes containing the title, author, no of pages and publisher. And then add a button to add it on the database, and I also have 3 listboxes containing the title, author and publisher. It seems that when I accomplished filling up the 4 textboxes and then clicking the button for insert, it's not updating the listboxes and even the database. Nothing is happening. How do you do that?
OleDbCommand cmd = new OleDbCommand();
OleDbConnection cn = new OleDbConnection();
OleDbDataReader dr;
public frm1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
cn.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Database2.accdb;Persist Security Info=True";
cmd.Connection = cn;
loaddata();
}
private void loaddata()
{
lstbxTitle.Items.Clear();
lstbxAuthor.Items.Clear();
lstbxPub.Items.Clear();
try
{
string q = "SELECT * FROM Table2";
cmd.CommandText = q;
cn.Open();
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
lstbxTitle.Items.Add(dr[1].ToString());
lstbxAuthor.Items.Add(dr[2].ToString());
lstbxPub.Items.Add(dr[6].ToString());
}
}
dr.Close();
cn.Close();
}
catch (Exception e)
{
cn.Close();
MessageBox.Show(e.Message.ToString());
}
}
private void lstbxTitle_Click(object sender, EventArgs e)
{
ListBox l = sender as ListBox;
try
{
if (l.SelectedIndex != 1)
{
lstbxTitle.SelectedIndex = l.SelectedIndex;
lstbxAuthor.SelectedIndex = l.SelectedIndex;
lstbxAuthor.Text = lstbxAuthor.SelectedItem.ToString();
lstbxPub.SelectedIndex = l.SelectedIndex;
lstbxPub.Text = lstbxPub.SelectedItem.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
if (txtbxAddT.Text != "")
{
string q = "insert into Table2 (Title) values ('" + txtbxAddT.Text.ToString() + "')";
txtbxAddT.Text = null;
}
if (txtbxAddA.Text != "")
{
string q = "insert into Table2 (Author) values ('" + txtbxAddA.Text.ToString() + "')";
txtbxAddA.Text = null;
}
if (txtbxAddNP.Text != "")
{
string q = "insert into Table2 (Page Number) values ('" + txtbxAddNP.Text.ToString() + "')";
txtbxAddNP.Text = null;
}
if (txtbxAddP.Text != "")
{
string q = "insert into Table2 (Publisher) values ('" + txtbxAddP.Text.ToString() + "')";
txtbxAddP.Text = null;
}
loaddata();
}
The problem is
you are not executing your query. It is in the string q, but you are not executing it anywhere.
Create a method:
private void UpdateData(query)
{
try
{
cn.Open();
cmd.CommandText = query; //set query to execute
cmd.ExecuteNonQuery(); //executing the query
cn.Close();
}
catch (Exception ex)
{
}
}
Call this method in every if-statement of method btnAdd_Click:
if (txtbxAddT.Text != "")
{
string q = "insert into Table2 (Title) values ('" + txtbxAddT.Text.ToString() + "')";
UpdateData(q);
txtbxAddT.Text = String.Empty; //Set it to "Empty", Null is not Empty
}
//... and so on for every if check
Best practice advice:
Assigning textbox.Text to "" or null is not a good practice.
Use String.Empty instead.
While checking for textbox.Text for being Empty, never use textbox.Text == null or textbox.Text == "", these are also not the best practices and some times create problems.
Use String.IsNullOrEmpty(textbox.Text) instead.
I can add, edit, delete database using listbox. But I want to do it using DatagridView I already bind it to my database.
How do I add,edit,delete update my database in datagridview using codes?
These are my codes:
namespace Icabales.Homer
{
public partial class Form1 : Form
{
SqlConnection cn = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=c:\users\homer\documents\visual studio 2010\Projects\Icabales.Homer\Icabales.Homer\Database1.mdf;Integrated Security=True;User Instance=True");
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;
SqlDataAdapter da;
DataTable dt = new DataTable();
public Form1()
{
InitializeComponent();
}
private void bindgrid()
{
string command = "select * from info";
da = new SqlDataAdapter(command, cn);
da.Fill(dt);
dataGridView1.DataSource = dt;
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'database1DataSet.info' table. You can move, or remove it, as needed.
this.infoTableAdapter.Fill(this.database1DataSet.info);
cmd.Connection = cn;
loadlist();
bindgrid();
}
private void button1_Click(object sender, EventArgs e)
{
if (txtid.Text != "" & txtname.Text != "")
{
cn.Open();
cmd.CommandText = "insert into info (id,name) values ('" + txtid.Text + "' , '" + txtname.Text + "')";
cmd.ExecuteNonQuery();
cmd.Clone();
MessageBox.Show("Record Inserted");
cn.Close();
txtid.Text = "";
txtname.Text = "";
loadlist();
}
}
private void loadlist()
{
listBox1.Items.Clear();
listBox2.Items.Clear();
cn.Open();
cmd.CommandText = "select * from info";
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
listBox1.Items.Add(dr[0].ToString());
listBox2.Items.Add(dr[1].ToString());
}
}
cn.Close();
}
private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
{
ListBox l = sender as ListBox;
if (l.SelectedIndex != -1)
{
listBox1.SelectedIndex = l.SelectedIndex;
listBox2.SelectedIndex = l.SelectedIndex;
txtid.Text = listBox1.SelectedItem.ToString();
txtname.Text = listBox2.SelectedItem.ToString();
}
}
private void button2_Click(object sender, EventArgs e)
{
if (txtid.Text != "" & txtname.Text != "")
{
cn.Open();
cmd.CommandText = "delete from info where id = '"+txtid.Text+"'and name = '"+txtname.Text+"'";
cmd.ExecuteNonQuery();
cn.Close();
MessageBox.Show("Record Deleted");
loadlist();
txtid.Text = "";
txtname.Text = "";
}
}
private void button3_Click(object sender, EventArgs e)
{
if (txtid.Text != "" & txtname.Text != "" & listBox1.SelectedIndex != -1)
{
cn.Open();
cmd.CommandText = "update info set id='"+txtid.Text+"',name='"+txtname.Text+"'where id='"+listBox1.SelectedItem.ToString()+"' and name='"+listBox2.SelectedItem.ToString()+"'";
cmd.ExecuteNonQuery();
cn.Close();
MessageBox.Show("Record Updated");
loadlist();
txtid.Text = "";
txtname.Text = "";
}
}
}
}
I have a dataGridView and a button on a form. When I do any editing, insertion or deletion in the dataGridView1, the code below does the magic
public partial class EditPermit : Form
{
OleDbCommand command;
OleDbDataAdapter da;
private BindingSource bindingSource = null;
private OleDbCommandBuilder oleCommandBuilder = null;
DataTable dataTable = new DataTable();
public EditPermit()
{
InitializeComponent();
}
private void EditPermitPermit_Load(object sender, EventArgs e)
{
DataBind();
}
private void btnSv_Click(object sender, EventArgs e)
{
dataGridView1.EndEdit(); //very important step
da.Update(dataTable);
MessageBox.Show("Updated");
DataBind();
}
private void DataBind()
{
dataGridView1.DataSource = null;
dataTable.Clear();
String connectionString = MainWindow.GetConnectionString(); //use your connection string please
String queryString1 = "SELECT * FROM TblPermitType"; // Use your table please
OleDbConnection connection = new OleDbConnection(connectionString);
connection.Open();
OleDbCommand command = connection.CreateCommand();
command.CommandText = queryString1;
try
{
da = new OleDbDataAdapter(queryString1, connection);
oleCommandBuilder = new OleDbCommandBuilder(da);
da.Fill(dataTable);
bindingSource = new BindingSource { DataSource = dataTable };
dataGridView1.DataSource = bindingSource;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
I have implemented a solution that inserts/updates/deletes data in MS SQL database directly from DataGridView.
To accomplish this I have used the following events: RowValidating and UserDeletingRow.
It is supposed that you have
SqlConnection _conn;
declared and initialized.
Here is the code:
private void dgv_RowValidating( object sender, DataGridViewCellCancelEventArgs e )
{
try
{
if (!dgv.IsCurrentRowDirty)
return;
string query = GetInsertOrUpdateSql(e);
if (_conn.State != ConnectionState.Open)
_conn.Open();
var cmd = new SqlCommand( query, _conn );
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show( ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning );
}
}
public string GetInsertOrUpdateSql( DataGridViewCellCancelEventArgs e )
{
DataGridViewRow row = dgv.Rows[e.RowIndex];
int id = 0;
int.TryParse( row.Cells["Id"].Value.ToString(), out id );
DateTime dob;
DateTime.TryParse( row.Cells["Dob"].Value.ToString(), out dob );
string email = row.Cells["Email"].Value.ToString();
string phone = row.Cells["Phone"].Value.ToString();
string fio = row.Cells["Fio"].Value.ToString();
if (id == 0)
return string.Format( "insert into {0} Values ('{1}','{2}','{3}','{4}')", "dbo.People", fio, dob.ToString( "dd-MM-yyyy" ), email, phone );
else
return string.Format( "update {0} set Fio='{1}', Dob='{2}', Email='{3}', Phone='{4}' WHERE Id={5}", "dbo.People", fio, dob.ToString( "dd-MM-yyyy" ), email, phone, id );
}
private void dgv_UserDeletingRow( object sender, DataGridViewRowCancelEventArgs e )
{
try
{
int id = 0;
int.TryParse( e.Row.Cells["Id"].Value.ToString(), out id );
string query = string.Format( "DELETE FROM {0} WHERE Id = {1}", "dbo.People", id );
var cmd = new SqlCommand( query, _conn );
if (_conn.State != ConnectionState.Open)
_conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show( ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning );
}
}
Hope this helps.
I have the same kind of project at home, I do not have the source code with me but if needed I can check somewhere this weekend to see what exactly I have done, but I believe it's some of the following:
Since you are using a dataset and a dataadapter this can be achieved very easily.
As long as your DataGridView1 has the properties enabled for users to add/delete/edit rows you could use the following code.
DataAdapter.Update(DataTable);
//in your code this would be:
da.Update(dt);
The DataAdapter.Update() Method will auto generate any insert/update/delete commands needed to update the results of your fill query compared with the current data in your datagridview.
You can set those commands (properties) as well in case you prefer to modify them, though this is not necessary.
This only works ofcourse after a user has made changes to the DataGridView. Add this code to a simple button and see if you have any luck. It definitly was something this simple :)