Need easy way out for change detection in dataset programatically c# - c#

what is the easiest way to find out those data which has been changed in dataset. i need point out programatically those data which has been modified.

DataSet changes = ds.GetChanges();
This will return a dataset with all the changes since the last time Accept or reject was called on the dataset.
You can also apply rowstatefilters i.e. if you want to see only those rows that have been modified:
DataSet changes = ds.GetChanges(DataRowState.Modified);
Or Added:
DataSet changes = ds.GetChanges(DataRowState.Added);

You can use GetChanges method on the DataSet object as described at : http://msdn.microsoft.com/en-us/library/a4ey25we.aspx

Related

Insert rows on a existing dataset

I have a dataset called "titulos" and have 1 table there called "tb"
with the columns with the name "titulo","titulo 2" and "titulo3".
I'm trying to do an insertion of rows in the event onclick of a button
but for some reason my code doesn't work!
My dataset is on a xsd file and I am using visual studio 2013 with c#.
I already tried this code but I don't know how to apply in my situation:
NorthwindDataSet.CustomersRow newCustomersRow =
northwindDataSet1.Customers.NewCustomersRow();
newCustomersRow.CustomerID = "ALFKI";
newCustomersRow.CompanyName = "Alfreds Futterkiste";
northwindDataSet1.Customers.Rows.Add(newCustomersRow);
The problem is that shows an error saying it does not recognize the dataset...
The erros is : "The name " Ds_Admissibilidade" does not exist in the current context
A DataSet is a disconnected copy of the data. It forgets if the data originated from database, an xml file or anything else. When you add rows to the DataSet, you only change the in-memory copy, not the original source.
You need some mechanism to update the source. For databases, a table adapter or dataadapter will do this for you. For a file source, you need to serialize the DataSet to the file, much the reverse of the way you read in in first place.
Hope this helps :)
DataRow newRow = titulos.Tables["tb"].NewRow();
newRow["titulo1"] = "titulo1";
newRow["titulo2"] = "titulo2";
newRow["titulo3"] = "titulo3";
titulos.Tables["tb"].Rows.Add(newRow);
Make sure you're setting all the values of the non nullable parameters. If you're using another instance of the dataset "titulos" use ImportRow instead of Add function.

Database not updating when using DataSet

I am doing a small project to learn how to use DataSet but i have a small problem. Consider following code:
foreach (DatabaseDataSet.ApplicationRow rowApplication in database.Application)
{
if (rowApplication.AID.ToString() == lblIDApplication.Text)
{
rowApplication.Date= tbApplicationDatum.Text;
rowApplication.Status = tbApplicationStatus.Text;
applicationAdapter.Update(rowApplication);
break;
}
}
I don't know why but the database doesn't get updated. The DataRow is being updated as when I call the data again I see the new value. But when I re-run my application it's back to it's old value again. Any help?
EDIT: I'm working with strongly typed DataSet
You need to call the Update method of your adapter to propogate the changes
AcceptChanges only updates the changes in memory for the row and does not migrate those to the database
MSDN
AcceptChanges and RejectChanges only apply to DataRow related changes
(that is, Add, Remove, Delete, and Modify). They are not applicable to
schema or structural changes.
Calling AcceptChanges will not replicate these changes back to the
data source if the DataSet was filled using a DataAdapter. In that
situation, call Update instead
See Updating Data Sources with DataAdapters for more information
Its important to remember that the DataSet is a 'local copy' of the data not a 'live link' to the DB. If your DataSet is populated by a IDataAdaptor (say a TableAdaptor) for example you need to call the DataAdaptors Update method passing in the Updated dataset to sync the results back to the underlying DB.
Also I would suspect you DONT want to be doing 'new ApplicationTableAdapter()' because typically you would want to update with the TableAdaptor you populated with, at the least you would need to ensure you had the correct connection, query etc set up.
SOLUTION: It happens that nothing was wrong with the code. I had two ConnectionString defined in App.config. I forgot to remove the first one after I removed a previous database that had errors in it. Upon removing the first ConnectionString, everything worked.

.Net Simple Data File usage

I've created a new project in .Net (2010 4.0) and added an SDF data file. I've generated a dataset and created a table in it (and I believe generated the Fill and other methods).
In code, I'm trying to add a row to the database.
eBureauScrubber.App_Data.matchingtempDataSet ds = new App_Data.matchingtempDataSet();
eBureauScrubber.App_Data.matchingtempDataSet.ctfFileRow row = ds.ctfFile.NewctfFileRow();
row.Address = "123 Main St.";
row.City = "Overland Park";
row.FirstName = "Matt";
row.LastName = "Dawdy";
row.rownum = 1;
EDIT: Added the next bit of code.
ds.ctfFile.Rows.Add(row);
ds.ctfFile.AcceptChanges();
ds.AcceptChanges();
eBureauScrubber.App_Data.matchingtempDataSetTableAdapters.ctfFileTableAdapter ctfa = new App_Data.matchingtempDataSetTableAdapters.ctfFileTableAdapter();
ctfa.Update(ds.ctfFile);
This runs fine. However, after the program completes, the data is not persisted in the database. What am I missing?
EDIT: I've tried all different combinations of AcceptChanges() on the datatable, the dataset, running update() before, after, etc. I'm missing something huge here. I'm not even sure it is connecting to the "right" database. Maybe that's my problem.
EDIT 2: Here's what I did to get this to work (it's still funky, though).
Change the properties of my DB file in App_Data to "Do Not Copy"
Manually copy that db file to bin\debug\app_data
Use the data adapter's fill method to fill the ds.ctfFile data table.
Create a row (.NewctfFileRow())
Set values on that row.
ds.ctfFile.Rows.Add(row)
ds.ctfFile.AcceptChanges();
ds.AcceptChanges();
Call the adapater's update method.
Now, the data is in my database file (in bin\debug\app_data), but I can't see it because the Data Sources connection. I'm still trying to find out how to do that.
It should have generated a TableAdapter class with a .Update() method that you have to call to save data in your database. See MSDN for some examples.

Merging Multiple ADO.NET DataSets

Scenario
I have a c# winforms application with a gridview.
The gridview datasource is populated by a dataset.
The contents of this dataset get updated every few seconds, and there are not always the same number of items in the dataset etc.
The dataset actually gets populated (or needs to get populated) by multiple other datasets being passed in one at a time.These datasets update at completely random times that cannot be controlled.
The Issue
Since essentially the GridView dataset is being "CONTINUALLY UPDATED" - At the time of an update(The point that a new dataset with the latest information in it needs to be merged with the existing GridView DataSource), I need to take a copy of the current dataset populating the gridview, compare it to the incoming data from the other dataset and update ONLY the data that is new.
So Far
I've tried a series of different methods but I can't seem to get this to work. I either end up with the dataset just being added to continually with duplicates of slightly different data, or the rows randomly get deleted (I tried using a merge all then delete approach which only works occasionally).
Any ideas how I can get around this!?
At the moment the gridview just updates itself to show the latest incoming dataset without the previous dataset merged into it.....
CODE - This randomly deletes the rows even though it does at some points display all data
//If the existing GridView dataset contains any rows that
//exist in the incoming latest dataset (matched on the two unique fields
//of the dataset), then remove that row from the existing GridView dataset
for (int i = 0; i < existingPriceResultsDTCopyForCompare.Rows.Count; i++)
{
foreach (DataRow incomingRow in incomingDS.Tables[0].Rows)
{
string incomingDate = incomingRow["Date"].ToString();
DataRow currentRow = existingPriceResultsDTCopyForCompare.Rows[i];
if ((currentRow["CCY"].ToString().Contains(incomingCcy))
&& (currentRow["Date"].ToString().Contains(incomingDate)))
{
existingPriceResultsDT.Rows.RemoveAt(i);
}
}
}
//Then merge the existing GridView dataset (Minus the old data that
//matches the data from the incoming Dataset with the latest information),
//With the brand new incoming data.
incomingDS.Merge(existingPriceResultsDT);
EDIT -
I'm beginning to wonder if the incoming dataset keeps being overwritten by the next incoming dataset before the iteration has time to complete. So I'm guessing I need to lock the incoming DataSet?
Have you tried something similar
DataSet ds1 = new DataSet();
DataSet ds2 = new DataSet();
ds1.Merge(ds2);
DataSet ds3 = ds1.GetChanges();
As per your Objects
DataSet existingPriceResultsDT = new DataSet();
DataSet incomingDS = new DataSet();
incomingDS.Merge(existingPriceResultsDT);
existingPriceResultsDT = incomingDS.GetChanges();
You might want to look into the Microsoft Sync Framework. This sounds like a perfect scenario for it. This video is a good introduction. You can also download the tutorials here.
That nested for-loop stuff is a big-O nightmare. You definitely want to get out of the business of looping through those rows - lots of unnecessary compares.
It looks like you've got a couple of columns there that you are comparing each time - "CCY" and "Date". Have you considered using them as the primary key for the table? If that makes sense for your scenario, you can make things considerably more efficient.
You could consider doing something like this:
Determine which columns are primary keys - it appears here that CCY and Date are for you.
DataColumn[] keys = new DataColumn[2];
keys[0] = dataTable.column["CCY"];
keys[1] = dataTable.column["Date"];
dataTable.PrimaryKey = keys;
Then when you read in a new DataSet - however you do that, call Merge on it like so:
dataSet.Merge(newDataSet, false, MissingSchemaAction.Add);
Assumption here is that dataTable is the Tables[0] of dataSet.
This, at least for my quick test program, will merge the two DataSets and update the rows that changed and add any new ones.
And, I just had my DataGridView set up like so:
dataGridView1.DataSource = dataSet.Tables[0];
Seemed to update the view well enough for my test program.
Hope that helps.

C# Reordering the Tables in a Dataset

I create a custom dataset that I pass off to a black boxed component. The dataset consists of usually 5-6 tables (with unique names assigned by me). The component takes the dataset and builds a drop down combo box based off the table names. What I am needing to do though is to change the ordering of the tables within the dataset. I need to do this so I first offer up to the user the appropriate selection in the drop down (based off what section in the application they are in). So for instance...if they are in "Section A" then that is the first table name shown in the drop down list...if the user goes to "Section F" then that is what is shown in the list first...so on and so forth.
The more code intensive way is of course to just change the ordering in which I add the tables to the dataset. This would work, but I thought there had to be some way to do this more elegantly and with less code.
I am working in C# with the 3.5 framework.
Remember that DataSets and their contents are stored on the heap, so you can have a DataTable object in more than one place in the DataSet.
Simply create your DataSet with a dummy DataTable in position zero. Then, based on whatever section they'e in, you put the corresponding table in position zero. Your table name will appear twice in your DropDownBox, once as the 'default' and again below in its proper context and order with the other tables.
public class ThisThing
{
private DataSet myDS = new DataSet();
//Populate your DataSet as normal
public DataSet ChangeLocation(int CurrentSectionNumber)
{
myDS.Table[0] = myDS.Table[CurrentSectionNumber]
}
}
I'm not sure trying to force your ordering information into the DataSet's data structure is the most intuitive approach. You might consider passing an ordered list of DataTable instead of (or in addition to) the DataSet.

Categories