Andrei Rinea

.NET Framework & SQL Server

Random thoughts..

clock August 25, 2009 04:36 by author Andrei Rinea
  • Hell is other people's code (no credit for me, I've read it elsewhere)
  • We need a garbage collector for code too, not just live instances (mine)


Using ADO.NET Data Servics in Silverlight 3 and eager loading parent entities

clock August 19, 2009 18:57 by author Andrei Rinea

We decided that in our Silverlight app that we develop we should not waste time writing WCF services manually to interact with data. So we turned to ADO.NET Data Services.  

I created a small Web App to host the ADO.NET Data Service which exposed the Entity Framework Model. All fine and dandy, being a bit pedant I created a very small console application just to add a service reference and test the data retrieval. All went well. Then I put the querying logic in the Silverlight app.

Something like

var employees = (from e in GetFreshContext().Employees select e).ToArray();

But upon running in Silverlight (in the console app it ran great) I get thrown with this exception : 

System.NotSupportedException: Specified method is not supported.
at System.Data.Services.Client.DataServiceQuery`1.System.Collections.Generic.IEnumerable<TElement>.GetEnumerator()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at MyApp.MainPage..ctor()
at MyApp.App.Application_Startup(Object sender, StartupEventArgs e)
at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)

WTF?! The very same code doesn't work in Silverlight no matter how I try. Searching on the web desperately, led me in the end to this nice post on the blog called (how ironically?) theproblemsolver : Consuming an ADO.NET Data Service from Silverlight written by Maurice De Beijer

It turns out you can't query synchronously in Silverlight although the exception did **NOT** contain any clue whatsoever regarding this although it should. The correct way :

var query = from t in GetFreshContext().Employee select t;
var dsQuery = (DataServiceQuery<Employee>)query;
dsQuery.BeginExecute(result =>
{
    ComboEmployees.ItemsSource = dsQuery.EndExecute(result).ToArray();
}, null);
ComboEmployees.DisplayMemberPath = "FullName";
 

Then I ran across another problem and it puzzled me for a while too until I found the answer. Specifically I needed to load the Department along with Employee (the entities are different in the real app). Retrieving the list of employees brought the Department property null.

I (might) retrieve a long list of employees so re-querying for each employee entity for the department would be a very costful operation (too many HTTP requests). Looking for solutions I came across Typed Eager Loading Using Entity Framework (& What is Eager Loading vs Deferred Loading) which solves the magic string problem of eager loading but I didn't really care about the string.

I needed the entities eager-loaded. However on Silverlight/ADO.NET Data Services I don't have the option of

DbDataContext.Categories.Include(“Products”)

as presented in the blog post.

Finally it turns out that, as John Papa describes in the MSDN Magazine (Using Silverlight 2 With ADO.NET Data Services), you have an Expand method :

var query = from t in GetFreshContext().Employee.Expand("Department") select t;
var dsQuery = (DataServiceQuery<Employee>)query;
dsQuery.BeginExecute(result =>
{
    ComboEmployees.ItemsSource = dsQuery.EndExecute(result).ToArray();
}, null);
ComboEmployees.DisplayMemberPath = "FullName";

Hope this helps


Tip : Middle click on tab

clock August 16, 2009 20:18 by author Andrei Rinea

Did you know that middle-clicking (that is clicking on the mouse's middle button - usually the wheel) on a tab in most decent software applications will close the tab? Here's a small list of applications which honor this :

  • Most main browsers (IE 7+, Opera 7.x+, Firefox 2.x+, Chrome 1.x+ - yes, Safari - doesn't)
  • Visual Studio
  • RSS Bandit (my RSS Reader of choice - have tried Google Reader and Feed Reader in the past but no thanks)

Why would this be useful? Because CTRL-F4 or searching for the "X" closing button might take more time and/or precision than middle clicking anywhere on the tab label up there :)