Debugging ADO.NET Data Services...with Fiddler2
When I deployed the small test application (http://www.silverlightdata.com/simple), it was pretty apparent that it was performing really badly. Some of this is because my ISP upload speed isn't great but it was still taking far too long I thought. This was a simple app with not much data, so I knew I wanted to find out what was happening. If you haven't seen the site, its basically an editor for the Product table in the Northwind database. Nothing special really.
ADO.NET Data Services does a lot of work for you under the covers. This is good because we're not being asked to write a lot of serialization and transportation code, but it can be bad because it becomes more difficult to see why things are happening. Fiddler2 to the rescue!
If you're not familiar with Fiddler2, its basically a great tool for watching web traffic so you can see what is actually happening over the wire. For ADO.NET Data Services, we want to see the actual communication over the wire to see what was being sent to and from the Silverlight application. First, grab the Fiddler2 tool (http://fiddler2.com/) and come with me!
So I fire up Fiddler2 and run the example page. What do I see? Nothing. None of the traffic is showing up. A quick Google search reveals that Fiddler doesn't work on localhost or 127.0.0.1 (kinda the same thing). I found an odd workaround...add a period after the IP address. So my "http://localhost:8000/Default.aspx" test page became "http://127.0.0.1.:8000/Default.aspx". The period after the "1" is not a mistake. Once I did that, the requests were showing up in Fiddler2. Wahoo!
So what did I see? Here's a look at the Fiddler2 window (You can click it for a bigger view):
Looking at the request to Products.svc, I picked the "TextView" tab to see the actual body of the message. Looking at it I noticed this Picture property that was base-64 encoded. Uh oh...I didn't even notice that we are getting pictures...in fact we're getting duplicate data. My LINQ request was:
var qry = from p in TheContext.Products.Expand("Supplier") .Expand("Category") orderby p.ProductName select p;
I knew that I would be getting duplicate data by using the Expand extension method. Expand says to embed the related entity (the Supplier and the Category) so that our object model doesn't have to lazy load them. Of course I wasn't paying attention. The Category has a picture stored in the database. I am not even using it (and couldn't since the image is a GIF and Silverlight can't display GIFs) so retrieving it is pretty useless. Here's a quick view of the underlying Entity model:
The fix for me was to simply remove it from the model, but I am looking at different ways of really solving it including delving into how the "select" statement might filter these out, though I expect that doing three queries (one for Products then just returning Suppliers and Categories to remove the duplicate data would be much more efficient yet.
One caveat, this is the first release of the ADO.NET Data Services' Silverlight Client Library so give it time to improve some of the performance issues. But like other data access libraries, sometimes small changes can make large improvements in performance.
Hope this helps you debug your own ADO.NET Data Services projects.