OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=\"C:\\Users\\User\\Desktop\\New Microsoft Access Database.accdb\"");
OleDbDataAdapter DataAdapter = new OleDbDataAdapter("SELECT *from pinakas", connection);
DataTable pinakas_Table = new DataTable();
DataAdapter.Fill(pinakas_Table);
MessageBox.Show(pinakas_Table.Rows[1]["Name"].ToString());
OK so this line displays the name "George" of my 1st Row of field
"Name".
pinakas_Table.Rows[1]["Name"] = "John";
Now this line sets field "Name" the value "John"
pinakas_Table.AcceptChanges();
DataAdapter.Fill(pinakas_Table);
MessageBox.Show(pinakas_Table.Rows[1]["Name"].ToString());
OK now my app displays the name "John" ! That means the DataTable "pinakas_Table" got the Change.
DataAdapter.Update(pinakas_Table);
But it's never saved to my Access database.
Updating Data Sources with DataAdapters states...
Calling AcceptChanges on the DataSet, DataTable, or DataRow will cause all Original values for a DataRow to be overwritten with the Current values for the DataRow. If the field values that identify the row as unique have been modified, after calling AcceptChanges the Original values will no longer match the values in the data source. AcceptChanges is called automatically for each row during a call to the Update method of a DataAdapter.
By calling pinakas_Table.AcceptChanges(); your modified row will be treated as if its data is unchanged from the database, so DataAdapter.Update(pinakas_Table); will see no action necessary for that row. Don't call AcceptChanges(). The Update method will call AcceptChanges() for you upon success.
Related
I am trying to figure out if I need additional logic to avoid a useless call to my SQL db, or if SqlDataAdapter.Update() will do the right thing. If I have this code:
SqlConnection sqlconn = new SqlConnection(connectionString);
sqlconn.Open();
SqlDataAdapter da = new SqlDataAdapter(selectString, sqlconn);
SqlDataTable table = new SqlDataTable();
da.Fill(table);
new SqlCommandBuilder(da);
table.Rows[0][columnName] = 5; // Existing value is already 5
da.Update(table);
Will .Update() still call SQL's UPDATE for that row, or will it not, because no values for the row really changed?
It will call the update statement in SQL, because changing a value in DataSet and setting it to same again, will modify the RowState property.
DataAdapter.Update - MSDN
When an application calls the Update method, the DataAdapter
examines the RowState property, and executes the required INSERT,
UPDATE, or DELETE statements iteratively for each row, based on the
order of the indexes configured in the DataSet.
You can also confirm it using SQL Profiler.
I am trying to delete the data present in the dataset with following code:
stateflowDataSet dsobject = new stateflowDataSet();
stateflowDataSetTableAdapters.dbo_statetableTableAdapter statetableadapter = new stateflowDataSetTableAdapters.dbo_statetableTableAdapter();
statetableadapter.Fill(dsobject.dbo_statetable);
dsobject.dbo_statetable.Clear();
statetableadapter.Update(dsobject);
But after this line when use statetableadapter.Fill(dsobject.dbo_statetable); the data is still retained.
Is the way in which I am clearing the data right?
Is there any other problem with the code?
Removing DataRows from a DataTable does not mean that you'll delete them from your DBMS. The opposite is true, actually you're preventing them from being deleted even if you would have called DataRow.Delete() before.
The reason is: only DataRows that belong to a DataTable can be deleted by
DataAdapter.Update(table)
This will delete every row in the table with DataRowState=Deleted.
Therefor you need to use the Delete method.
foreach(DataRow row in dsobject.dbo_statetable.Rows)
{
row.Delete();
}
statetableadapter.Update(dsobject.dbo_statetable);
You could do it also in one batch which would be more efficient, therefor you need to set the DataAdapter's UpdateBatchSize to 0(unlimited).
Another way would to delete all rows is to use a simple SqlCommand with CommandText DELETE FROM Table:
using(var con = new SqlConnection(ConfigurationSettings.AppSettings["con"]))
using(var cmd = new SqlCommand())
{
cmd.CommandText = "DELETE FROM Table";
cmd.Connection = con;
con.Open();
int numberDeleted = cmd.ExecuteNonQuery(); // all rows deleted
}
Now you need to remove(not delete, what is the core of your question) the rows from the DataTable manually since you've also deleted them manually in the database:
dsobject.dbo_statetable.Clear();
Let me try re-wording Tims answer a little. I used DataSets alot when they were popular, and was confused with their 'magic'...
Dataset contains copy of the data from the database + your updates on the data since data is fetched from the database.
Update() method on the DataAdapter with your dataset isn't magic, it goes through your tables in the dataset, and in tables it scan rows. It will:
use DeleteCommand if row is marked for deletion
use UpdateCommand if row is marked for update
Former is the case when you delete a row with Delete() method, and later is the case when you update some cell in the row.
You will learn much about the process if you observe RowState property of each row in the dataset tables.
I'm having an issue with writing back to my Access Database (.accdb) through using a DataAdapter.
Currently, I have a Fill method which fills a DataSet Table up with data. This piece of code is currently sitting within my Form_Load().
// TODO: This line of code loads data into the 'hCAliasDataSet.Topics' table. You can move, or remove it, as needed.
this.topicsTableAdapter.Fill(this.hCAliasDataSet.Topics);
Then I have an cmdAdd_Click() event, this is obviously to add a new row into the Topcis table that sits within the hCAliasDataSet.
// Create a new row, append it to Topics table.
DataRow DR;
DR = this.hCAliasDataSet.Tables["Topics"].NewRow();
this.hCAliasDataSet.Tables["Topics"].Rows.Add(DR);
Next, I've created some code to caputre the input of one of the column values.
// Capture user input
sTopicName = Interaction.InputBox("Please Enter Topic Name", "Topic Name", null, 100, 100);
// Set the Topic value for the new Row
DR["Topic"] = sTopicName;
My problem, I'm assuming is here, where I call the dataAdapter to update the Topics table. I manually check the database, and there aren't any new rows created?
// Commit the changes back to the hCAlias DataBase (hcalias.accdb).
this.topicsTableAdapter.Update(this.hCAliasDataSet.Topics);
Edit: I believe I'm needing to create an INSERT query, for my TableAdapter, would this be correct?
The adapter should generate the insert statement automatically for you behind the scenes.
Your code looks right, but it's possible that you have a constraint on one of your columns that makes it unable to save. (like a non-nullable column that you didn't specify any data for). But, you'd usually get an exception if there was a constraint that cancelled the insert.
You can try one of these alternatives, but they're basically the same thing:
this.topicsTableAdapter.Update(this.hCAliasDataSet);
this.topicsTableAdapter.Update(DR);
this.topicsTableAdapter.Insert(sTopicName); // add any other columns in here
You should call AcceptChanges in your dataset:
hCAliasDataSet.AcceptChanges();
And then commit to the database with your TableAdapter.
The Update() method just updates existing records, you'll need to use the TableAdapter Insert() method to add a new row. VC# will have created a default Insert() method for you, (which may be overloaded)... but there will be a method that will let you explicitly insert values....
For example...
this.topicsTableAdapter.Insert(int Column1, string Column2 etc etc)
This will create a new row in your database and populate it with the values you specify.
How do I read data from a DataSet in WPF? I have a train schedule table with just 2 columns and I want to be able to read the departure times and calculate when the next train is leaving. For example, the time now is 12:29 and my application should tell me that next train will depart at 12:33.
I already googled left and right. I'm on .NET 3.5.
DataSet resembles database. DataTable resembles database table, and DataRow resembles a record in a table. If you want to add filtering or sorting options, you then do so with a DataView object, and convert it back to a separate DataTable object.
If you're using database to store your data, then you first load a database table to a DataSet object in memory. You can load multiple database tables to one DataSet, and select specific table to read from the DataSet through DataTable object. Subsequently, you read a specific row of data from your DataTable through DataRow. Following codes demonstrate the steps:
SqlCeDataAdapter da = new SqlCeDataAdapter();
DataSet ds = new DataSet();
DataTable dt = new DataTable();
da.SelectCommand = new SqlCommand(#"SELECT * FROM FooTable", connString);
da.Fill(ds, "FooTable");
dt = ds.Tables["FooTable"];
foreach (DataRow dr in dt.Rows)
{
MessageBox.Show(dr["Column1"].ToString());
}
To read a specific cell in a row:
int rowNum // row number
string columnName = "DepartureTime"; // database table column name
dt.Rows[rowNum][columnName].ToString();
If ds is the DataSet, you can access the CustomerID column of the first row in the first table with something like:
DataRow dr = ds.Tables[0].Rows[0];
Console.WriteLine(dr["CustomerID"]);
If this is from a SQL Server datebase you could issue this kind of query...
Select Top 1 DepartureTime From TrainSchedule where DepartureTime >
GetUTCDate()
Order By DepartureTime ASC
GetDate() could also be used, not sure how dates are being stored.
I am not sure how the data is being stored and/or read.
TL;DR: - grab the datatable from the dataset and read from the rows property.
DataSet ds = new DataSet();
DataTable dt = new DataTable();
DataColumn col = new DataColumn("Id", typeof(int));
dt.Columns.Add(col);
dt.Rows.Add(new object[] { 1 });
ds.Tables.Add(dt);
var row = ds.Tables[0].Rows[0];
//access the ID column.
var id = (int) row.ItemArray[0];
A DataSet is a copy of data accessed from a database, but doesn't even require a database to use at all. It is preferred, though.
Note that if you are creating a new application, consider using an ORM, such as the Entity Framework or NHibernate, since DataSets are no longer preferred; however, they are still supported and as far as I can tell, are not going away any time soon.
If you are reading from standard dataset, then #KMC's answer is what you're looking for. The proper way to do this, though, is to create a Strongly-Typed DataSet and use that so you can take advantage of Intellisense. Assuming you are not using the Entity Framework, proceed.
If you don't already have a dedicated space for your data access layer, such as a project or an App_Data folder, I suggest you create one now. Otherwise, proceed as follows under your data project folder:
Add > Add New Item > DataSet. The file created will have an .xsd extension.
You'll then need to create a DataTable. Create a DataTable (click on the file, then right click on the design window - the file has an .xsd extension - and click Add > DataTable). Create some columns (Right click on the datatable you just created > Add > Column). Finally, you'll need a table adapter to access the data. You'll need to setup a connection to your database to access data referenced in the dataset.
After you are done, after successfully referencing the DataSet in your project (using statement), you can access the DataSet with intellisense. This makes it so much easier than untyped datasets.
When possible, use Strongly-Typed DataSets instead of untyped ones. Although it is more work to create, it ends up saving you lots of time later with intellisense. You could do something like:
MyStronglyTypedDataSet trainDataSet = new MyStronglyTypedDataSet();
DataAdapterForThisDataSet dataAdapter = new DataAdapterForThisDataSet();
//code to fill the dataset
//omitted - you'll have to either use the wizard to create data fill/retrieval
//methods or you'll use your own custom classes to fill the dataset.
if(trainDataSet.NextTrainDepartureTime > CurrentTime){
trainDataSet.QueueNextTrain = true; //assumes QueueNextTrain is in your Strongly-Typed dataset
}
else
//do some other work
The above example assumes that your Strongly-Typed DataSet has a column of type DateTime named NextTrainDepartureTime. Hope that helps!
I am loading my ADO.net dataset in by select query in command object. If I clear the dataset data with Acceptchanges will it delete the data in the sql server.
If not Please let me Know how to do?
No, it will not.
You will have to make sure that each DataRow in your DataTable is marked as 'Deleted'. That is, the rowstate of each row will have to be set to Deleted.
You can do that by traversing all rows, and call the Delete method for each Row.
Then, you'll have to call the Update method of the DataAdapter, before you call AcceptChanges. You have to call 'AcceptChanges' after you've done the changes in the DB, to indicate that the dataset / datatable does not contain anymore changes that have to be persisted in the DB.
(Calling AcceptChanges will remove the DataRows that have a RowState of 'Deleted', and will change the RowState of all other DataRows to 'UnChanged'.