I received an excellent question following last week's webcast on persisting data returned from Windows Live Services (and similar RSS & non-RSS services). As you'll recall, in the webcast we showed using a Typed DataSet as an easy way to manage and persist RSS data; the Typed DataSet was generated using the RSS returned by http://qna.live.com. This person's question specifically addressed the issue of merging two DataSets containing RSS data.
The problem the person is encountering is that when they attempt to merge the two DataSets, that the merge fails because of the AutoIncrement columns that are created on the rss & channel DataTables. The issue occurs because these AutoIncrement columns (which are also supposed to be unique) are starting with values of zero (0) in both DataSets; therefore, when the DataSets are merged, there is a conflict.
In the scenario we've been working in where the first DataSet is populated prior to populating the second DataSet, one easy way I've found to deal with this issue is to simply set the AutoIncrementSeed value on the tables in the new DataSet to start at a higher value then the largest value in the first DataSet.
Using a function like the following you can find the largest value of the AutoIncrement column in the rss DataTable (rss_id) and then return the next value to use:
private int GetNextRssId()
{
// Get idx of the last row of rss table
int idxLastRssRow = existingDataSet.rss.Rows.Count - 1;
// Get the rss_id from last rss row
return existingDataSet.rss[idxLastRssRow].rss_Id + 1;
}
And do the same thing for the channel_id column on the channel DataTable.
private int GetNextChannelId()
{
// Get idx of the last row of channel table
int idxLastChannelRow = newDataSet.channel.Rows.Count - 1;
// Get the channel_id from the last channel row
return newDataSet.channel[idxLastChannelRow].channel_Id + 1;
}
With this, you can set the AutoIncrementSeed on the rss and channel DataTables in the new DataSet to start at the non-overlapping value as shown here:
NewDataSet tempDataSet = new NewDataSet();
tempDataSet.channel.channel_IdColumn.AutoIncrementSeed = GetNextChannelId();
tempDataSet.rss.rss_IdColumn.AutoIncrementSeed = GetNextRssId();
With non-overlapping values, you can now populate the second DataSet and merge it with the original without difficulty.
But wait, there's more…
Merging the two RSS-filled DataSets works well, especially if you need to operate on the two RSS feeds separately before combining them. However, if all you want to do is add additional feeds to the existing DataSet, you don't have to populate a separate DataSet then merge them; you can instead read the additional feeds directly into the DataSet as we did when populating the original DataSet.
As you'll recall, when we populate the original DataSet, we read 1 feed at a time from the HTTP stream into the DataSet. There's no reason this same technique can't be used to add more feeds later.
You can download an updated QnA RSS Feed Sample that adds two new menu options "Get More RSS then Merge" and "Get More RSS - Read Directly" that demonstrates adding feeds to the original DataSet by merging the DataSets and reading directly into the original DataSet respectively.
Overlapping Feeds…
One thing you'll want to be sure and remember is that both of these techniques assume that you're adding new feeds. If you'll being doing a mixture of refreshing existing feeds and adding new feeds, you'll want to be sure to add the appropriate logic as to whether you should add a whole new RSS entry or simply update the details of an existing RSS entry.
Posted
Jan 31 2007, 08:45 AM
by
jim-wilson