Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


The Mind of an Angry Coder: Waiting to Inhale : Page 2

The recent Professional Developer Conference (PDC) fostered great excitement about the power of the .NET Framework v2.0. Unfortunately, it is going to be well into next year before most developers even get a whiff of all things Whidbey; and that's only in beta form. Some important .NET language and framework enhancements are in a big holding pattern, though, and I don't think that's right.

Secretary of RowState
I have never been a big fan of transmitting DataSets via Web services because they tend to be pretty bloated. I prefer to send arrays of entity classes via .NET Remoting. However, I had a client recently that wanted to use the batch updating feature of DataSets on a PocketPC device using the .NET Compact Framework. For various reasons (most notably feature lock in, configuration, and security issues) they wanted to avoid using Remote Data Access (RDA) and Merge Replication to get data from their Web service (the .NET CF doesn't support Remoting) into SQL Server CE on a PDA.

What I needed to do to get this process working optimally was change the RowState property of each DataRow object to DataRowState.Added inside the Web service before I sent it over the wire to the PocketPC device, so that all it had to do was use a SqlDataAdapter object and a SqlCommandBuilder object to batch insert the contents of the DataSet into SQL Server CE. Unfortunately, the RowState property of the DataRow class is read only, so I had to get a bit creative.

I came up with two approaches that accomplish what I needed. The first was to serialize the DataSet to an XML string, manually insert the HasChanges="inserted" DiffGram hint using string manipulation, then deserialize the string back into a DataSet object:

//...load DataSet into variable ds...// XmlSerializer serializer = new XmlSerializer(typeof(DataSet)); MemoryStream ms = new MemoryStream(); serializer.Serialize(ms,ds); string xml = Encoding.ASCII.GetString(ms.ToArray()); ms.Close(); xml = xml.Replace("<Table","<Table diffgr:hasChanges=\"inserted\""); ds = (DataSet)serializer.Deserialize(new MemoryStream(Encoding.ASCII.GetBytes(xml)));

The approach shown above worked relatively well, but since serialization requires Reflection, and a host of other "not so speedy" processes, I sought out a faster solution that was less of a "hack." The approach below is nearly three times as fast as the serialization example:

//...load DataSet into variable ds2...// ds2 = ds.Clone(); for(int i=0;i<ds.Tables[0].Rows.Count;i++) { ds2.Tables[0].Rows.Add( ds.Tables[0].Rows[i].ItemArray); }

Note that you need to clone the source DataSet in order to preserve its schema, which will enable the batch update process on the PocketPC device to work properly. You then loop through the source DataSet and copy each row to the target DataSet. This adds the "inserted" hint to the DiffGram for each row. You have to use the ItemArray property of each DataRow >object, because a DataRow reference cannot be assigned to more than one DataTable (it generates an exception).

Sadly, the RowState property of the DataRow class is still read only in the .NET Framework v2.0. I'll request the change, though, and perhaps the Microsoft machine will respond favorably. Until next issue, stay angry and don't follow the rules that suck. My name is Jonathan Goodyear and I am the angryCoder.

Jonathan Goodyear is a regular contributor to CoDe Magazine.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date