How to replace a DataBase Table by a DataTable - c#

I am trying to replace a Table (FooTable) in my DataSource (an SQL CE Database) by a DataTable (which bind to a DataGrid). The reason I want to do this is: after I populate from a Database to a DataSet (which show all the rows on the DataGrid), I might edit, delete, and add multiple rows to the DataTable. Instead of updating my changes to DataSource (SQL CE) each time I modified the DataTable, I want to do it collectively at the end of the session.
My approach is straight-forward:
`DELETE` all data from my DataSource table (FooTable) (I'm using **SQL CE**, so `TRUNCATE` is not available)
INSERT the `DataTable's` data in to the emptied DataSource Table
Following is my C# code
/* Truncate the DataSource Table */
SqlCeCommand delCmd = new SqlCeCommand("DELETE FROM FooTable", conn)
conn.Open();
delCmd.ExecuteNonQuery();
conn.Close();
/* Insert DataTable into an empty DataSource Table */
string ins = #"INSERT INTO FooTable (FooName) values (#fooName)";
SqlCeCommand cmd = new SqlCeCommand(ins, conn);
da.InsertCommand = cmd;
da.Update(ds, "FooTable");
The codes work if I add or delete rows on the DataTable, but when I edit a specific row on the DataTable and Insert the table to my DataSource, I get the following error
"Update requires a valid UpdateCommand when passed DataRow collection with modified rows."
I do not understand why I get this error. I have already empty all rows in my DataSource table and my DataSource shouldn't not know there are modified rows but insert all DataTable Rows as new rows.
Or, is there a simple way to "REPLACE" a DataSource table by a DataTable?
[EDITED]
I tried setting the RowState manually like below code
foreach (DataRow row in dt.Rows)
{
row.RowState = DataRowState.Added;
}
but RowState is only read only and cannot be written.
[EDITED - 2nd]
I tried setting it using SetAdded()
foreach (DataRow row in dt.Rows)
{
row.SetAdded();
}
Then I get the following error:
"SetAdded and SetModified can only be called on DataRows with Unchanged DataRowState."
Still not manage to get it to work...
[EDITED - 3rd]
So finally get it to work with the following code:
using (SqlCeCommand insCmd = new SqlCeCommand(#"INSERT INTO FooTable (FooName) VALUES (#fooName)", conn))
{
insCmd.Parameters.Add("#fooName", SqlDbType.NVarChar, 10, "FooName");
dt.AcceptChanges();
foreach (DataRow row in dt.Rows)
{
row.SetAdded();
}
da.InsertCommand = insCmd;
da.Update(ds, "FooTable");
}

The DataTable tracks RowStates internally.
When you modify an existing row, its RowState becomes Modified, so the DataAdapter tries to run an UPDATE command.
You need to call the SetAdded() method on the modified rows to set their RowStates to Added rather than Modified.

Related

c# - fastest way to insert value from DataReader into DataGridView

I need to load the data from SQLite, then show the data in DataTable to display in DataGridView. The current approach I am using is read the data from DataReader, then loop through reader.Read() to create each DataRow.
The performance is slow for above method because I have 600k rows of data row. I had tried to use dataTable.Load(reader), but it is even slow then previous. Is there any fastest way to add the data from SQLite into DataTable.
SQLiteCommand command = new SQLiteCommand(sql, connection);
SQLiteDataReader reader = command.ExecuteReader();
while(reader.Read())
{
DataRow dRow = dataTable.NewRow();
dRow[''] = reader[''].ToString();
......
......
......
dataTable.Rows.Add(dRow);
}
This is just a option which you might not care.
What you're doing now is, one by one, inputing 600,000 value into each column of row(of dataTable) and if columns of new row are completely inserted, the new row is added to the DataTable.
Your code inside while reading loop seems just constructing a new row and adding it to dataTable.
If you don't need to manipulate each value while reading loop which means you only need datas as they're,
SQLiteCommand command = new SQLiteCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(commmand);
da.Fill(dataTable);
dataGridView.ItemsSource= dt.DefaultView;

How to Populate the unbounded datagridview from SQL Server database in C#?

In My Project I'm Using Unbounded datagridview with 33 columns for storing the user data in database and I need to populate the datagridview after each and every Insert, Update and Delete.
My Problem is while populating the datagridview with sql server query it shows the column header repeated with data.
my code is given below :
Private Void PopulateGrid()
{
cs.open();
sqladpter da= new sqlcommand("Select * from Customer",cs);
DataTable dt =new datatable();
da.fill(dt);
datagridview.datasource=dt;
datagridview.Refresh();
}
I'll Call This method at the End Of each and every Insert, Update and Delete.
How about Using something simple like datasource and you can have all your CRUD operations
http://msdn.microsoft.com/en-CA/library/dz12d98w(v=vs.100).aspx
try setting DataSource = null before setting new DataSource
datagridview.DataSource = null;
datagridview.DataSource = dt;

adding datarow to datagridview only adding to first column

I'm trying to pull a set of data from a database and shove it in to a datagridview. Problem is, when I do this, I get "system.data.datarow", and it only adds it to the first column (I've got 5). Here's my code.
SqlCommand sqlCom = new SqlCommand("some SQL query string", "SQL database connection info");
SqlDataAdapter adapter = new SqlDataAdapter(sqlComm);
DataTable table = new Datatable();
if (methodType = "SELECT")
{
sqlConn.Open();
adapter.fill(table);
foreach (DataRow row in table.Rows)
{
dgvCrsLookupResults.Rows.Add(row[0]);
dgvCrsLookupResults.Rows.Add(row[1]);
dgvCrsLookupResults.Rows.Add(row[2]);
dgvCrsLookupResults.Rows.Add(row[3]);
dgvCrsLookupResults.Rows.Add(row[4]);
}
}
Obviously, this only fills in the first column, but I can't figure out for the life of me how to add it to each column instead. When I use
dgvCrsLookupResults.Columns.Add(row[0]);
It just says that it has invalid arguments. I know I'm damn close, but I'm new to all of this, so I'm completely lost as to how to make that last jump. Thoughts?
Instead of looping foreach(DataRow row in table.Rows) use:
dgvCrsLookupResults.DataSource = table;
Remember set:
dgvCrsLookupResults.AutoGenerateColumns = True;
Or in designer create a columns for your DataGridView.
In column set DataPropertyName = ColumnName in DataTable
In this case -> dgvCrsLookupResults.AutoGenerateColumns = False;

Single datagridview row updating

Could you help with such problem:
I have two forms, datagridview and SQL database.
On Load event of my first form I'm select some data from my SQL database by using stored procedure(select query).
SqlConnection con = new SqlConnection(constr);
SqlCommand cmd = new SqlCommand("PROC001", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
datagridview.DataSource = dt;
After that, I can filter or sort my datagridview by using dt.DefaultView.Filter = .... and display in my grid only filtered rows.
On CellMouseDoubleClick event my second Form2 appearing. In this form I update some value in database by clicking on Button1 and also after that I want to update my selected datagridview row. My quetions are:
1) How can I update only selected row in datagridview and do not execute stored procedure for all datagridview filling again.
2) My datagridview is already filtered, so if I execute procedure again, my filter has been disapeared. How can I avoid of this?
3) On Form2 I'm updating some database value, that is not included in my "select query" as selected field, but this value is affected on this query. Example:
SELECT Name, SecondName FROM tUsers
WHERE id = (SELECT DISTINCT id FROM tProcedures WHERE Code = 'First')
In my datagridview I can see Name and SecondName, but in Form2 I'm updating Code in tProcedures database table. So after updating I want to see my new data in datagridview, only in selected row and with current filter. I don't want to SELECT all data again to datagridview and broke my filter.
Is it possible to update single row? Could you provide some examples?
Because the DataGridView is using DataBinding, you have to update the underlying data source, in this case the DataTable. See How to: Edit Rows in a DataTable for how to do that.
For the filter issue, you would want to save and restore the filter:
var filter = dt.DefaultView.RowFilter;
UpdateData();
dt.DefaultView.RowFilter = filter;

Inserting just a new record using DataSet (.net c# ado.net )

I've a form containing more than 200 text boxes in .NET desktop application. I want to insert them into their respective 4 tables of Database. Now how should I go about it using Dataset & DataAdapter to do this?
I mean usually this will be the flow:
Populate the DataSet using DataAdapter.Fill(Dataset,"DataTable");
manipuate the data of DataSet
DataAdapter.Update(Dataset,"DataTable") updates the content back to Database.
Code:http://dev.mysql.com/doc/refman/5.1/en/connector-net-tutorials-intro.html#connector-net-tutorials-data-adapter
But here I just want to insert a new record in 3 different tables.
I think the way is to
Programmatically Create A dataset with 3 Datatables.
Bind 200 Textboxes to respective columns of these Datatabes
dataAdapter.Update(dataSet, dataTable.TableName);
Am I right?
How does dataAdapter.Update(dataSet, dataTable.TableName); work? Because, my each dataTable will have only one record. (the new record that is to be inserted. binded with those 200 TextBoxes of the form) where as the Table of the Database will have thousands of records. If I do dataAdapter.Update(dataSet, dataTable.TableName); will it delete all the rest of the records and insert this one alone?
I just want to insert a new record (without fetching other 1000s of records into my Dataset) into Database.Table using Dataset.
Each row has a RowState Property, this will be used by the dataAdapter. So if your dataset has only one new row, the row state will be DataRowState.Added. The DataAdapter will insert the row and change the row state to DataRowState.Unchanged. All other rows in the database will be unchanged.
IDbTransaction dbTransaction = dbConnection.BeginTransaction();
try
{
foreach (DataTable dataTable in dataSet.Tables)
{
string sql = "SELECT * FROM " + dataTable.TableName + " WHERE 0 = 1";
SqlDataAdapter dataAdapter = new SqlDataAdapter (sql, dbConnection);
dataAdapter.Update(dataSet, dataTable.TableName);
}
}
catch
{
dbTransaction.Rollback();
throw;
}
dbTransaction.Commit();
Remark: Will not work if there are constraints in the database defined.
Simply make the SQL insert commands and execute them:
string cmd="insert into myTable(column1, column2, etc) values (#text1,#text2, etc)";
SqlCommand sqlcmd=new SqlCommand(cmd,mySqlConnection);
sqlcmd.Parameters.Add("#text1",SqlDbType.NChar,textbox1.Text);
sqlcmd.Parameters.Add("#text2",SqlDbType.NChar,textbox2.Text);
sqlcmd.ExecuteNonQuery();

Categories