I'd like to know if it's a bad practice. I have a page of datagrid of 50 rows with about 10 text boxes in each row. Page function is very simple with just a button to update and save in ms sql. When user clicks the button, it takes long time to save. I am using update in a sql loop with a hidden id field id. What is the best way to simply update table?
for (int i=0; i<options_bind.Items.Count; i++)
{
if (((CheckBox)options_bind.Items[i].FindControl("check_Save")).Checked )
{
call sql update one by one here
}
}
Use SqlCommanBuilder to bind data to datagridview
sqlDataAdapter = new SqlDataAdapter(selectQueryString, sqlConnection);
sqlCommandBuilder = new SqlCommandBuilder(sqlDataAdapter);
dataTable = new DataTable();
sqlDataAdapter.Fill(dataTable);
bindingSource = new BindingSource();
bindingSource.DataSource = dataTable;
yourDataGridView.DataSource = bindingSource;
And then on update event
try
{
sqlDataAdapter.Update(dataTable);
}
catch (Exception exceptionObj)
{
MessageBox.Show(exceptionObj.Message.ToString());
}
Related
I am currently working on a database system. In the system a user can search for a specific member using their ID. Searching for them filters all DataGridView results to just that specific member.
private void button3_Click(object sender, EventArgs e)
{
dataGridView1.ReadOnly = false;
using (SqlConnection con = new SqlConnection(constring))
{
int id = Convert.ToInt32(textBox1.Text);
con.Open();
DataTable FindAaron = new DataTable();
SqlDataAdapter adapt = new SqlDataAdapter("SELECT * FROM MembersTable WHERE MemberID =" + id, con);
adapt.Fill(FindAaron);
dataGridView1.DataSource = FindAaron;
con.Close();
}
}
This code filters the DataGridView results down to one row from the table 'MembersTable'. The user can now physically click on the table cell and edit the data as much as they want. Once they are finished they hit a 'Save Changes' button which I want to save the changes they made, update the source table and refill the DataGridView with all the members, now with updated info. This is the code I have behind the 'Save Changes' button at the moment.
try
{
//MemberClass.UpdateMember();
this.membersTableTableAdapter.Update(mainDatabaseDataSet.MembersTable);
dataGridView1.Refresh();
MessageBox.Show("Details updated");
}
catch
{
MessageBox.Show("An error has occured");
}
This unfortunately does not update the DataGridView in the form to display all the updated data or save the data that has been edited back to the Sql table. Have puzzled over this for a few days and can't figure out what I'm doing wrong. Any and all help is much appreciated.
Actually there is no connection seen between membersTableTableAdapter and adapt or mainDatabaseDataSet.MembersTable and FindAaron.
Try as following;
//Get the changed data
DataTable changes = FindAaron.GetChanges();
if (changes != null)
{
//Update data
adapt.Update(changes);
}
I have created a DataGrid and I take the data from database and put it in there.All the data retrieval are done by dynamically in the code behind.Here is a some portion of my code.
SqlConnection con = new SqlConnection("Data Source=PUNUTHL\\SQL;Initial Catalog=mytest;Integrated Security=True");
SqlDataAdapter ad;
DataSet ds = new DataSet();
static DataTable dt = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ad = new SqlDataAdapter("Select * from product",con);
ad.Fill(ds);
dt = ds.Tables[0];
DataGrid1.DataSource = dt;
DataGrid1.DataBind();
}
}
Upto this point it works perfectly.
But I wanted to add the edit function for that DataGrid
But according to my query I took the "product_ID" values as well which can not allows to be updated.
Since I use both "Etid" and "Delete" commands, "prodcut-id" may be my 3rd column as shown in the picture.
So I wanted to be that column read only when the client hit on the edit button.So how can I tackle this problem.Are there any way to get the column names or column indexed?Please can some one help me.
This is one of the way to make a column at any index readonly.
DT.Columns(0).ReadOnly = True '// Make the column(0) readonly and assign to DataGrid.
Datagrid!.DataSource = DT
where DT is datatable used to collect the data from database and is datasource to the datagrid Datagrid1.
For further editing make the column readonly= false and make changes and again turn it into readonly.
Here in your case you can make your Id column that is 2 as readonly
I am trying to make a simple winform application in which i could read/update and insert data to MS Access db table
When i run the application it reads data from MS Access db, and I am able to add new data or edit existing data, but those changes are not sent back to DB.
Code in my Save button click event
Validate();
myBindingSource.EndEdit();
//myTableAdapterManager.UpdateAll(myDataSet.myTable); //this line was in generated code
myTableAdapter.Update(myDataSet.myTable); //replaced previous row with this one, but with no effect
When I press the "save" button
I do not receive any error message, in the DataGridView, new row contains ID with -1 value and new row is not added to database
What could be the problem? What am I missing?
When I opened mdb file from MS Access 2007 it is possible to add a new row to this table
This SO post seems to be about the same problem, but it does not help in my case
unable to add new row using datagridview using C# in Winforms
[EDIT]
I opened .xsd file and added Insert and Update Queries for myTable, but still that does not help - when i press Save button changes are not sent to the database
I found the solution how to send data from Grid control to database, i hope it will help someone else as well (+added some usefull additional stuff)
Here is my code
//form level fields
OleDbConnection conn = new OleDbConnection();
OleDbDataAdapter adapter;// = new OleDbDataAdapter();
DataTable table = new DataTable();
BindingSource bSource = new BindingSource();
//choosing MS Access file
var ecgDbFile = new OpenFileDialog();
ecgDbFile.InitialDirectory = "c:\\";
ecgDbFile.Filter = #"MS Access files (*.mdb)|*.mdb";
ecgDbFile.FilterIndex = 1;
ecgDbFile.RestoreDirectory = true;
//creating connection
conn.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ecgDbFile.FileName;
conn.Open();
//A nice way how to get a list of Data base's tables
var restrictions = new string[4];
restrictions[3] = "Table";
userTableList = conn.GetSchema("Tables", restrictions);
//then loop through and you can get table names => userTableList.Rows[i][2].ToString()
//reading the data (in the grid)
adapter = new OleDbDataAdapter("Select * from "+TableName, conn);
adapter.Fill(table);
bSource.DataSource = table; //binding through bindingsource
GridControl.DataSource = bSource; //actually it works fine if GridControl.DataSource is set to table directly as well...
//choose the appropriate trigger (some gridcontrol or button click event) to call for database updates
private void GridControl_Leave(object sender, EventArgs e)
{
//because of this OleDbCommandBuilder TableAdapter knows how to insert/update database
OleDbCommandBuilder command = new OleDbCommandBuilder(adapter);
adapter.Update(table);
}
I have a DataSet + TableAdapter and bound dataGridView. I have an edit button which opens a new form with details to edit (WinForms). How do I refresh one row (selected one) in the Dataset and in dataGrid from database before opening the new form?
Example: Two users A and B. User A changed record ID(10) and user B still has the old value in record ID(10). User B presses edit button and should get fresh data from database (data after change made by user A).
string sql = "SELECT * FROM Orders";
SqlConnection connection = new SqlConnection(connectionString);
SqlDataAdapter da = new SqlDataAdapter(sql, connection);
DataSet ds = new DataSet();
connection.Open();
da.Fill(ds, "Orders");
connection.Close();
dataGridView1.DataSource = ds;
.....
private void button1_Click(object sender, EventArgs e)
{
//?
//refresh selected row in datagrid (from current database record)
//?
EditForm()
}
Create a new query in your TableAdapter that should only get one row and call it with just the primary key of the row you already have.
Plug the result into a new DataSet and grab the first row (after checking for Rows.Count() > 0)
I would enclose the populating the gridview bit in it's own method say something like fill_grid(). Then just call the method in the edit link click event. Then whatever has changed will update. Then add the method to all the other button link events too. Then every time the user is clicking a link the grid "refreshes" essentially.
For those who is looking for the answer in 2019,
assuming dataAdapter is a defined earlier class member
private void ButtonUpdate_Click(object sender, RoutedEventArgs e)
{
if (dataGrid.SelectedItem is DataRowView view)
{
DataRow currentRow = view.Row;
DataTable table = currentRow.Table;
dataAdapter.Fill(table.Rows.IndexOf(currentRow), 1, table);
}
}
Okay guys,
After many readings and finding solutions down here I just need to ask this.
I already searched for it but it didn't help me as good as it should to sort this out.
Also, excuse me for my grammatical mistakes if any...
What's the problem?
I load up a WPF form with a combobox in. This combobox gets all the names from all the tables in my database. I choose a table name and press a button to fill up a DataGrid (WPF) with the chosen table. This all works perfectly. But, then when I changed a cell or added/deleted a row or column I have to update this to the database.
This is where I'm stuck. I got it working trough a not so optimal way. So that's why I ask if there is a better solution.
//fill the datagrid with data from chosen table in combobox!
selectedTable = cboxTables.SelectedItem.ToString();
dataset = db.getDataFromTable(selectedTable);
datatable = dataset.Tables[selectedTable];
datagridAdmin.ItemsSource = datatable.DefaultView;
And when the selection in the DataGrid has changed, I set the 'Submit' button as active wich calls this code:
db.updateTable(selectedTable, datatable);
Note that 'db' is a instance off my databaseclass. The method is as following:
public bool updateTable(String tableName, DataTable datatable)
{
using (SqlBulkCopy bulkcopy = new SqlBulkCopy(thisConnection.ConnectionString, SqlBulkCopyOptions.CheckConstraints))
{
//Set destination table name
//to table previously created.
bulkcopy.DestinationTableName = tableName;
try
{
thisCommand = new SqlCommand("DELETE FROM " + tableName, thisConnection);
thisCommand.ExecuteNonQuery();
bulkcopy.WriteToServer(datatable);
}
catch (Exception ex)
{
logger.WriteLine(applicationName, ex.Message);
}
}
}
But the problem is, the first column is a auto increment ID wich keeps raising every time I submit the changed DataGrid.
Isn't there a better way to do this?
Thanks!
PS: I'm coding in Visual Studio 2010 with C# in WPF.
In short for the method you have given you would be better off using the Truncate table method before calling your bulk copy, this will reset the Identity column back to 0:
thisCommand = new SqlCommand("TRUNCATE TABLE " + tableName, thisConnection);
However either method is going to cause problems with foreign keys in your database. I am not sure how you are retrieving your data in your database class, but I would look at using the SqlCommandBuilder to update your database rather than deleting and re-inserting all the data with each update.
EDIT
To further explain my suggestion of the SqlCommandBuilder.
A ViewModel such as the following should allow use of the SqlCommandBuilder (Note: this is hugely cut down and in real terms this requires better validation, exception and event handling, but the rough idea is there):
public class YourViewModel
{
private SqlDataAdapter adapter;
private DataTable table;
private SqlCommandBuilder commandBuilder;
public DataTable Table { get { return table; } set { table = value; } }
public void LoadTable(string connectionString, string tableName, int[] primaryKeyColumns)
{
adapter = new SqlDataAdapter(string.Format("SELECT * FROM {0}", tableName), connectionString);
table = new DataTable();
adapter.Fill(table);
List<DataColumn> primaryKeys = new List<DataColumn>();
for (int i = 0; i < primaryKeyColumns.Length; i++)
{
primaryKeys.Add(table.Columns[primaryKeyColumns[i]]);
}
table.PrimaryKey = primaryKeys.ToArray();
commandBuilder = new SqlCommandBuilder(adapter);
commandBuilder.GetUpdateCommand();
}
public int Update()
{
if (table == null || table.Rows.Count == 0 || adapter == null)
{
return 0;
}
if (table.PrimaryKey.Length == 0)
{
throw new Exception("Primary Keys must be defined before an update of this nature can be performed");
}
else
{
return adapter.Update(table);
}
}
}
Bind the Table property to the grid view, then call the Update method when required. You can even bind the update to the table's rowchanged events etc to automatically update the db. The Code Project has a fairly good article on WPF, Data grids and database integration.