Reputation: 619
I get a DataTable from a DataSet and then bind that DataTable to a DataGridView. Once the user edits the information on the DataGridView how do I take those changes and put them back into a DataTable that was used that I can then put back into my DataSet?
I want to make a Save Button on my DataGrid that when pressed actually saves the changes.
I don't if I can get anymore specific than that, because it is a fairly simple question.
Thanks in advance!
Let me know if you need me to elaborate more.
Upvotes: 10
Views: 41325
Reputation: 3234
With dataTable.GetChanges() you can get changes as a list. Iterating through them you can apply insert/update/delete operations. Here is a sample save button saving the changes to oracle db from DataGridView.
I implemented insert and update. You can simply implement delete too. Also note that I assumed the tables has first column as primary key for simplicity. You can alter the code to use it for multiple column pks. Table is dynamically selected from a ComboBox.
private void button_SaveToDb_Click(object sender, EventArgs e)
{
using (OracleConnection conn = new OracleConnection())
{
conn.ConnectionString = textBox_ConString.Text;
conn.Open();
var dataTable = (DataTable)dataGridView1.DataSource;
var changes = dataTable.GetChanges();
if (changes != null)
{
foreach (DataRow row in changes.Rows)
{
switch (row.RowState)
{
case DataRowState.Added:
OracleCommand command = new OracleCommand()
{
Connection = conn,
BindByName = true
};
var qry = $"INSERT INTO {comboBox_Tables.SelectedItem.ToString()} (";
StringBuilder sb = new StringBuilder();
int i = 0;
foreach (var col in row.Table.Columns)
{
sb.Append(col + ((i == row.Table.Columns.Count - 1) ? "" : ","));
command.Parameters.Add(new OracleParameter(col.ToString(), row.ItemArray[i]));
i = i + 1;
}
sb.Append(") VALUES (");
i = 0;
foreach (var col in row.Table.Columns)
{
sb.Append(":" + col + ((i == row.Table.Columns.Count - 1) ? "" : ","));
command.Parameters.Add(new OracleParameter(col.ToString(), row.ItemArray[i]));
i = i + 1;
}
sb.Append(")");
command.CommandText = qry + sb;
command.ExecuteNonQuery();
break;
case DataRowState.Deleted:
break;
case DataRowState.Modified:
command = new OracleCommand()
{
Connection = conn,
BindByName = true
};
qry = $"UPDATE {comboBox_Tables.SelectedItem.ToString()} SET ";
sb = new StringBuilder();
i = 0;
foreach (var col in row.Table.Columns)
{
if (i > 0)
{
sb.Append(col + "=:" + col + ((i == row.Table.Columns.Count - 1) ? "" : ","));
}
command.Parameters.Add(new OracleParameter(col.ToString(), row.ItemArray[i]));
i = i + 1;
}
command.CommandText = qry + sb + $" WHERE {row.Table.Columns[0]} = :{row.Table.Columns[0]}";
command.ExecuteNonQuery();
break;
}
}
((DataTable)dataGridView1.DataSource).AcceptChanges();
}
}
}
Upvotes: 0
Reputation: 3989
as mentioned DataAdapters are one of the easy ways.
See: http://www.codeproject.com/KB/database/relationaladonet.aspx
for a pretty simple example that I think covers what youu need.
Upvotes: 0
Reputation: 1063058
If you are using data-binding to a DataGridView
, then you are already updating the DataTable
/ DataSet
. If you mean changes down to the database, then that is where adapters come into play.
Here's an example:
using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
DataSet set = new DataSet();
DataTable table = set.Tables.Add("MyTable");
table.Columns.Add("Foo", typeof(int));
table.Columns.Add("Bar", typeof(string));
Button btn;
using (Form form = new Form
{
Text = "DataGridView binding sample",
Controls =
{
new DataGridView {
Dock = DockStyle.Fill,
DataMember = "MyTable",
DataSource = set
},
(btn = new Button {
Dock = DockStyle.Bottom,
Text = "Total"
})
}
})
{
btn.Click += delegate
{
form.Text = table.AsEnumerable().Sum(
row => row.Field<int>("Foo")).ToString();
};
Application.Run(form);
}
}
}
Upvotes: 6