Why is the DataTable not empty even after it has been cleared?
In the beginning I cleared the the "PasswoerterDataTable". But afte updating and filling it back it is not empty anymore. Did I misunderstood the usage of the .fill and .update commands? How do I correct my mistake so that the "PasswoerterDataTable" is empty in the end?
PasswoerterDataTable.Rows.Clear();
// DataTable is now empty
PasswoerterTableAdapter.Update(PasswoerterDataTable);
PasswoerterTableAdapter.Fill(PasswoerterDataTable);
// DataTable is not empty anymore. Why?
I know that it does not make sense to use .update and .fill after each other but I am currently working on a PasswordManager and I want to delete Passwords. These deleted Passwords should not appaer when the program is closed and started again but I need to use .fill after Startup to get the Passwords which haven't been deleted. But after I used .fill the Passwords reappear.
The Fill method exists to read data from a database table and put it inside an in memory DataTable object. I think you are misunderstanding the work of the Clear method and the Update method.
The Clear method removes all rows from the in memory datatable but doesn't change anything on the database table. The Update method looks at the rows present in your PasswoerterDataTable and checks their RowState property. If it finds something to update then a command is executed to reflect the changes back to the database.
But you have cleared the rows from PasswoerterDataTable so Update has nothing to update and your database table is left unchanged. The following Fill reloads everything.
If you want Update to execute delete commands on the database you need to set the RowState of each row to Deleted. And you can do this with
foreach(DataRow row in PasswoerterDataTable.Rows)
row.Delete(); // This doesn't remove the row, but sets its RowState to Deleted
// Now the adapter knows what to do...
PasswoerterTableAdapter.Update();
Of course this is totally unnecessary and you can simply write a single Command to act directly on your database to TRUNCATE your table
SqlCommand cmd = new SqlCommand("TRUNCATE TABLE PasswoerterTable", connection);
cmd.ExecuteNonQuery();
PasswoerterDataTable.Rows.Clear();
// No need to call Fill again.
Related
I am iterating through a DataView. If I don't want a row based on a predefined condition, I am deleting it. After I iterate through the entire DataView, I want to bind this updated DataView back to a control but not commit the changes to the SQL Server Database table. Will this automatically trigger the deletes in the actual sql server table? If so, how can I stop that from happening.
foreach (DataRowView dR in dvUpdatedRankings)
{
// If some logic is true, delete row
if(DeleteFlag == True)
{
dR.Delete();
}
}
The dataview is no way related to sql server db..It serves just as holder to save the value fetched from db,, any modification done to it will only reside in servers memory till the scope of the object is lost. Hence db would not be changed.
It is like a one way communication.. you got the data from db to DataView. and the connection is closed and now db and Dataview are two seperate things!
After deleting the rows from the dataset, call dataset.Acceptchanges().
That will reremoved the rows from the dataset that are marked as "to_be_deleted".
I have a table within my program which stores information about messages and would like to detect when new information has been added to it. The reason I am doing this is beucause I would like to show the new data to the user only when there is new data instead of having to constantly get all the rows and display them.
The way I decided to do this was through the use of the dataSet.HasChanged() function which should essentially check the dataset for any new rows and a function called DataChanged returns dataSet.HasChanged() value.
However, the function I am using always returns false (even when there are changes)
Here is the function...
public bool DataChanged(string Table)
{
//This is the variable that will be returned
bool ChangesMade;
//Create the adapter
OleDbDataAdapter adapter = new OleDbDataAdapter(Table, connector);
//Clear the current data in the dataset
dataSet.Clear();
//Open the connection and fill the dataset
connector.Open();
adapter.Fill(dataSet, "TableData1");
connector.Close();
return ChangesMade = dataSet.HasChanges();
}
Changes for some reason are never detected and therefore this function always returns false even after I add a new record to the dataset.
An alternative method that provides the functionality explained in paragraph one would be very helpful and the fixing of my current method ever more so.
Here is an easy way to do this.
Make sure a Timestamp/Rowversion column exists for each table you wish to track changes to.
Return the current database Timestamp to your calling program as part of your data result set (DataSet in this case). For example, add the following query to your result set.
SELECT ##DBTS;
Use this returned value the next time you run your query with the following added to the existing WHERE clause(s) as appropriate.
...
AND (#LastRowversionValue IS NULL
OR TableName.RowversionColumn > #LastRowversionValue)
...
Pass NULL for the #LastRowversionValue the first time the query is ran to get the process started.
Any rows that are inserted/updated into the table(s) since the last time you retrieved data, will have an Rowversion greater than the one you stored from the last execution.
usersTableAdapter usersTA = new usersTableAdapter();
var usersTable = new users.usersDataTable();
usersTA.Fill(usersTable);
VK_BDayParser.users.usersRow row = usersTable.FindByid(currentItem.id);
row.BeginEdit();
row.last_name = "********";
row.EndEdit();
row.AcceptChanges();
usersTable.AcceptChanges();
int result = usersTA.Update(usersTable);
SQL server 2012.
I used generated classes from VS 2013 to database
I try to update row in my DB, in 'usersRow row' this changes works, but in DB has no changes. What am I doing wrong? result is always 0.
This is a common misunderstanding on what the AcceptChanges method does.
I think the problem arises from the initial comment in the documentation of the AcceptChanges method .
Commits all the changes made to this table since the last time
AcceptChanges was called.
Many people think that this means 'commits to the database table', instead it means 'commits to the in-memory instance of the datatable object'.
Then, the following comment on the docs, hints to what is really happening there.
When AcceptChanges is called, any DataRow object still in edit mode
successfully ends its edits. The DataRowState also changes: all Added
and Modified rows become Unchanged, and Deleted rows are removed.
So, there is this DataRow.RowState property that express what is the current state of the in-memory rows belonging to the in-memory instance of the DataTable. And it is this state that helps the DataAdapter.Update method in discovering what to do with the rows.
In other words the Update method decides to update the database table only for the rows that are not RowState==DataRowState.Unchanged. But calling AcceptChanges 'commits' these rows and their state becomes Unchanged. No update then.
I have a function that returns a typed DataRow object and now I would insert this DataRow in a given table. As far as I know I could do this using TableAdapter in two ways: TableAdapter.Update and TableAdapter.Insert.
Both ways seems pretty simple to use but, first way could even delete row from the table (essentially my DataSet will be "serialized" on my DB table) and since this table is really the application's critical part I would avoid any chance of data deletion, so I would prefear Insert method.
The problem seems to be that Insert method doesn't accept a DataRow object as it's parameter (unlike Update), so I need to manually insert each parameters. Alas I have at least 80 parameters so this is a really really headache operation. What can I do now?
The update method does allow you to insert,update or delete changes in the tableAdapter. MSDN: 'Use the TableAdapter.Update method when your application uses datasets to store data. The Update method sends all changes (updates, inserts, and deletes) to the database'. Although Insert is ment for usage if you want more control for you data inserts but does not allow you to pass a datarow instead Parameters must be used. See complete reference on MSDN: http://msdn.microsoft.com/en-us/library/ms233812(v=vs.110).aspx
Code example of Update method usage.
// Create a new row.
NorthwindDataSet.RegionRow newRegionRow;
newRegionRow = northwindDataSet.Region.NewRegionRow();
newRegionRow.RegionID = 5;
newRegionRow.RegionDescription = "NorthWestern";
// Add the row to the Region table
this.northwindDataSet.Region.Rows.Add(newRegionRow);
// Save the new row to the database
this.regionTableAdapter.Update(this.northwindDataSet.Region);
Code example Insert:
NorthwindDataSetTableAdapters.RegionTableAdapter regionTableAdapter =
new NorthwindDataSetTableAdapters.RegionTableAdapter();
regionTableAdapter.Insert(5, "NorthWestern");
Sorry if the title is a bit vague, but I'm trying to think of a good way to do this right now. We are using .NET 3.5, by the way.
Example code:
if (ExistsInDB(dt.Rows.Find(rowID)))
dt.Rows.Find(rowID).Delete();
else
dt.Rows.Remove(dt.Rows.Find(rowID));
If the row exists in the database, mark it for deletion. Otherwise, remove it from the datatable.
Now, if I go ahead and change the DataRow's RowState property to Deleted via the DataRow.Delete() method, that works fine except I can't access information I would need to delete the row from the database when the user hits "Save Changes".
I don't want to store the rows in another datatable because I already have a lot of other data tables and I don't want to add more complexity to the object. I would put another column on the datatable with the name "ToBeDeleted" or something, but the tables get displayed in the program via a grid.
Essentially, I want to be able to flag a DataRow in a DataTable for deletion in the database later without resorting to throwing the DataRow into a List or adding another column to it. Is this possible?
You can get the deleted row's data by writing
row["ColumnName", DataRowVersion.Original]
Why not use DataAdapter for this? You can learn how to do this at http://msdn.microsoft.com/en-us/library/xzb1zw3x%28v=VS.90%29.aspx
Thanks,
Vamyip