Help with DataAdapter - DB doesn't update? - c#

I have a data adapter. When I check the function at runtime I see the changes, but nothing happens in the database. How do I debug this? What went wrong?
OleDbDataAdapter adapter = new OleDbDataAdapter();
string queryString = "SELECT * FROM tasks";
OleDbConnection connection = new OleDbConnection(cn.ConnectionString);
adapter.SelectCommand = new OleDbCommand(queryString, connection);
OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter);
connection.Open();
adapter.Fill(ds.Tables["Tasks"]);
adapter.Update(ds);
return ds;

Nothing is happening in the database because you're running a SELECT query. What are you expecting to happen?

Well unless you snipped a lot of code, you are not changing anything in the dataset per se.
What are you trying to achieve?
Here, you are selecting some data, filling the dataset with it, then putting back the unchanged dataset in the DB.
You should first change something in the dataset itself before calling adapter.Update(ds)
Cheers,
Florian

You are selecting data via the SelectCommand. If you want to update data, you need to run the UpdateCommand.

I assume you didn't post the full source code, as it looks as though you're not modifying the dataset. However, I just tweaked your code a bit (see my comments).
Hopefully this will help...
string queryString = "SELECT * FROM tasks";
OleDbConnection connection = new OleDbConnection(cn.ConnectionString);
connection.Open(); // open connection first
SqlCommand cmd = new SqlCommand(queryString, connection);
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd); // use the cmd above when instantiating the adapter
OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter);
adapter.Fill(ds.Tables["Tasks"]);
// Modify your dataset here.
// Don't call AcceptChanges() as this will prevent the update from working.
adapter.Update(ds);
connection.Close(); // Close connection before ending the function
return ds;
This should allow OleDbCommandBuilder to do its thing by automatically scripting the database updates.

As far as I can see you've not actually changed any of the contents of the tasks table. When you call adapter.Fill you are populated the empty dataset with the records from the database. You are then calling adapter.Update without changing any records within the dataset. The update command only performs changes when the dataset > datatable > datarows are edited and marked as dirty.

you are only specifying the select command. you also need to specify the insert command... i.e:
DataAdapter.InsertCommand = new OleDbCommand....

Related

Read in a databse table but only get one field

I have a table with four text fields but when I execute the following I only get one field in the DataGridview. I am not geting all the records either I dont think. How to fix it so I get all the fields and records? text= table name this is in a function/method. Is it the query thats fouling things up?
string connetionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\temp\\Set.mdb;Persist Security Info=False";
string sql = "SELECT Property, PValue, PDefault, PType FROM "+text;
OleDbConnection connection = new OleDbConnection(connetionString);
OleDbDataAdapter dataadapter = new OleDbDataAdapter(sql, connection);
DataSet ds = new DataSet();
connection.Open();
dataadapter.Fill(ds, text);
connection.Close();
dataGridView1.DataSource = ds;
dataGridView1.DataMember = text;
There's a myriad of things that could be wrong. But none of them are evidenced in your question.
Your DataGridView might not have the correct columns added, or doesn't have AutoGenerateColumns = true.
You haven't mentioned if the data is actually missing from the dataset, or if it's just your view that's broken. Wouldn't you KNOW you're not getting all the records back? Not just have a hunch? Breakpoint that line, Sir!
Have you tried running that command directly on the database? Are the results good there?
I expect the answer will be that the data is fine, but the view is not showing all the data, Data...

DataSet call insert, update and delete stored procedures

Through designer I have created a typed data set and included stored procedures for insert / update / delete. The problem is now, how to call those stored procedures? How to actually change data in database this way? And how to receive answer from db (number of rows changed)?
try this for get data from database.
DataSet ds = new DataSet("dstblName");
using(SqlConnection conn = new SqlConnection("ConnectionString"))
{
SqlCommand sqlComm = new SqlCommand("spselect", conn);
sqlComm.Parameters.AddWithValue("#parameter1", parameter1value);
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = sqlComm;
da.Fill(ds);
}
Similarly you need to call "spdelte" etc.
I found out that far easiest way is through designer - create table adapter and simply set it to call stored procedure. No extra typing needed, arguments are also added to procedure call.

DataAdapter: Update unable to find TableMapping['Table'] or DataTable 'Table'

This code snippet is throwing an error:
Update unable to find TableMapping['Table'] or DataTable 'Table'.) on adapter.Update(ds); line
Why it is throwing this type of error?
SqlConnection con = new SqlConnection();
con.ConnectionString = connectionString();
DataSet ds = new DataSet();
string strQuery = "SELECT * FROM Cars";
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(strQuery, con);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.Fill(ds, "Cars");
//Code to modify data in the DataSet
ds.Tables["Cars"].Rows[0]["Brand"] = "NewBrand";
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.Update(ds);
Use
adapter.Update(ds, "Cars");
instead.
I have tested it. I got the same error without and it works if i specify the tablename. However, i must admit that i yet don't know why the DataAdapter needs to know the table-name since it has all informations it needs. If i useds.GetChanges i get one row with the correct table-name.
Update I have found nothing on MSDN but finally found it in the source(ILSpy). Here is the implementation of DBDataAdapter.Update(DataSet):
public override int Update(DataSet dataSet)
{
return this.Update(dataSet, "Table");
}
So if you don't specify a table, the table-name "Table" is used and if you've specified a table-name other than that you'll get this error, that's really strange!
I assume that the reason for this is that the DataAdapter cannot call GetChanges to determine the table to update for two reasons:
It would be inefficient since it needs to loop all tables and all of their rows to find rows with a RowState != Unchanged
It's possible that multiple tables needs to be updated since they contain changed rows. That is not supported via DataAdapter. Hence DataAdapter.Update(DataSet) assumes the default name "Table" as table-name.
Edit: However, maybe someone can explain me why the DataAdapter doesn't use DataSet.Tables[0].TableName instead.
So in general it seems to be best practise to specify the name of the table you want to update.
It's because .NET cannot assume that the table name in the DataSet/DataTable is identical to the database table. Thus .NET warns you about it.
To solve it you need to add a mapping to the DataAdapter:
da.TableMappings.Add("TableNameInDb", "TableNameInTheDataSet");
However, even if you have specified a name in the DataSet or the DataSource it still doesn't work, since the adapter seems to forget the name.
I only got it working by using:
da.TableMappings.Add("Table", "TableNameInDb");
I agree with jgauffin and I will only explain it with more text.
First, I must explain how TableMapping works. If we don't specify TableMappings with SqlDataAdapter (SqlDataAdapter that will fill our DataSet) then by default the first table will be named "Table", the second will be named "Table1", the third will be named "Table2" etc.
So, when we want to name DataTable in DataSet, we use it like this:
System.Data.DataSet myDataSet = new System.Data.DataSet();
using (System.Data.SqlClient.SqlDataAdapter dbAdapter = new System.Data.SqlClient.SqlDataAdapter(dbCommand))
{
dbAdapter.TableMappings.Add("Table", "Cars");
dbAdapter.TableMappings.Add("Table1", "Trucks");
//...
dbAdapter.Fill(myDataSet);
}
And only then we can modify it like this:
myDataSet.Tables["Cars"].Rows[0]["Brand"] = "Toyota";
myDataSet.Tables["Trucks"].Rows[0]["Brand"] = "MAN";

Update using MySqlDataAdapter doesn't work

I am trying to use MySqlDatAdapter to update a MySql table. But, the table never updates!!! I did this before but with SQL server. Is there anything else that is specific to MySql that I am missing in my code?
DataTable myTable = new DataTable("testtable");
MySqlConnection mySqlCon = new MySqlConnection(ConfigurationManager.ConnectionStrings["DBConStr"].ConnectionString);
MySqlCommand mySqlCmd = new MySqlCommand("SELECT * FROM testtable WHERE Name = 'Tom'");
mySqlCmd.Connection = mySqlCon;
MySqlDataAdapter adapter = new MySqlDataAdapter(mySqlCmd);
MySqlCommandBuilder myCB = new MySqlCommandBuilder(adapter);
adapter.UpdateCommand = myCB.GetUpdateCommand();
mySqlCon.Open();
adapter.Fill(myTable);
myTable.Rows[0]["Name"] = "Was Tom";
myTable.AcceptChanges();
adapter.Update(myTable);
mySqlCon.Close();
Thanks
Remove myTable.AcceptChanges() before the update. Othwerwise that will set all rows RowState to Unchanged, hence the DataAdapter will not know that something was changed.
adapter.Update(myTable) will call AcceptChanges itself after the update is finished.
So...
myTable.Rows[0]["Name"] = "Was Tom";
//myTable.AcceptChanges();
adapter.Update(myTable);
My some one need to look into the following solution; In other scenario people may need different solution. Even Don't do any manipulation with Datatable when you Debug at Run-time like this,
myTable.GetChanges(); // Return Any of Chnages Made without applying myTable.Accepchanges()
myTable.GetChanges(DataRowState.Added); // Return added rows without applying myTable.Accepchanges()
myTable.GetChanges(DataRowState.Deleted);
myTable.GetChanges(DataRowState.Detached);
myTable.GetChanges(DataRowState.Modified);
myTable.GetChanges(DataRowState.Unchanged);
You may get Data According to the above commands. So better try to debug before you pass the datatable to update or insert or delete command.
If myTable.GetChanges() return null then you can SetAdded() or SetModified() back to your DataTable;
foreach(DataRow row in myTable.Rows)
{
row.SetAdded(); // For Insert Command
row.SetModified(); // For Update Command
}

Remove Row through DataAdapter

I've initialized a dataAdapter :
string sql = "SELECT * From localitati";
da1 = new System.Data.SqlClient.SqlDataAdapter(sql, con);
da1.Fill(ds1, "localitati");
And this works just fine. The problem is when i try to delete a record and update the database.
I remove a record from the dataset as such :
ds1.Tables["localitati"].Rows.Remove(dRow);
And this works just fine as well(verified).
The problem is when i update the DataAdapter, the DataBase doesn't get modified :
con.Open()
da1.Update(ds1, "localitati");
con.Close();
What could be the problem ?
What fixed it for me was to call the Delete method on the DataRow instead of the Remove method on the DataTable.
ds.Tables["localitati"].Rows.Find(primaryKeyValue).Delete();
or just simply
dr.Delete();
You need to make sure you've set the da1.DeleteCommand - this is the command that will be fired for each row in the DataTable that has been deleted. See this MSDN reference for example.
try below code
assuming that Database is not throwing any exception.
con.Open()
da1.Update(ds1.Tables["localitati"].GetChanges());
con.Close();
In the code that you have posted only the SelectCommand is set for the DataAdapter.
You could use the following code to generate the Insert, Update and Delete commands for da1.
string sql = "SELECT * From localitati";
da1 = new SqlDataAdapter(sql, con);
SqlCommandBuilder builder = new SqlCommandBuilder(da1);
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";
da1.Fill(ds1, "localitati");
The CommandBuilder however should be used only for relatively simple scenarios (details). For he rest is recommended to write your own commands that rely on custom command texts/stored procedures.
If it still doesn't work, you could start a SQL Server Profiler on the server to trace what command gets to the database when you execute the Update method.
DataRow dr = datatable.Rows.Find(key);
int Index = datatable.Rows.IndexOf(dr);
BindingContext[DataTable].RemoveAt(Index);
BindingContext[DataTable].EndCurrentEdit();
dataAdapter.Update(DataTable);
DataTable.AcceptChanges();

Categories