Umbraco as a data source

My favourite aspect of Umbraco is the backoffice.  I am continually blown away by the data type/property editors which have been written for data entry.  Before I begin I’d like to outline some of my favourites: 

  • The Slider.  Seriously, does it get any simpler than this?

  • The Multi-Node Tree Picker.  If you want one-to-many or many-to-many relationships, look no further.

  • The Image Cropper.  Crop images with zero effort – how many CMS’s have one of these?

  • The “Dropdown list multiple”.

 

Now, these make data entry a breeze, and I think that is where Umbraco’s strength lies.  However, Umbraco has a few weaknesses if you’re a developer that needs to use that data.   If you want to use Umbraco as a data source like the Entity framework or the (now obsolete) LinqToSql, these are the things that will stand in your way:

  1. Poor referential integrity.  When you are defining relationships, you have no idea whether those referenced nodes exist until you try to instantiate them.  Existence checks litter your code, and that should not be necessary.
  2. Expensive querying.  With the introduction of uQuery to the code in v4.8, we have come a long way – you can get Nodes by alias, and traverse the tree with ease.  It also makes querying Members, Media and Documents a breeze.  However, querying a large collection of nodes with uQuery is slow.  With the exception of UQL (which is alpha, unsupported and very good) there is nothing that comes close to implementing IQueryable over the Umbraco data store.  You have few options when you’re querying large sets of nodes: use examine, or buy more RAM and cache the crap out of a whole bunch of Nodes.
  3. Nodes are not strongly typed.  If you’ve ever used uSiteBuilder before, you will be very aware of how nice it is to work with strongly typed node.  By default, all your nodes, regardless of their document type, are basically Dictionaries with a few standard properties.  LinqToUmbraco once presented a solution to this but has been dropped because of its performance issues.

 

We’ve recently been working on a site at Wiliam which has relationships galore and plently of gnarly querying (if you’ve ever built an eCommerce site with complex discounts you know what I mean).  We chose Umbraco as the back office, but decided to go with MVC4 to manage the routing, shopping cart and rendering (including a mobile version of the site, which MVC4 supports natively).  Later on we also included the Entity framework to use some custom tables.

When I say we were using MVC4 for the front-end, I mean there is absolutely no Umbraco related code in the front-end.  Data comes from a separate data project which shields the Entity/Umbraco dependencies, giving us flexibility for the future and a lot more control over optimisation.  (I won’t go into how we got Umbraco and ASP.NET MVC to play nice together in the same project, but it’s possible with some Web.config inheritance and tweaking.)

When I began, I was manually mapping Nodes to strongly typed POCOs which the data layer would retrieve.  It became quite obvious that a lot of repetition was going on here, and being familiar with AutoMapper, I decided I should automate the process.  That’s when I whipped up uMapper, which is my response to the above qualms.  After many late nights and missed train stations, it was mapping properties, relationships and understanding the POCOs’ inheritance hierarchy.  As of uComponents 5.3.0 (of which it is a component), it will support filtering on individual properties.  This is necessary when you use custom routing – you don’t want to instantiate a thousand nodes when you only need one.

uMapper will probably not be a permanent fixture in the Umbraco world, and it currently does not use Umbraco v6’s new `IPublishedContent` services.  However, it demonstrates that an Umbraco data source really can be hidden behind a services layer with minimal effort, and I think that is what .NET developers would really like to see in future releases of Umbraco. 

One day we will conversing with Umbraco through IQueryable, but until that day, we will have to settle for third party or custom plugins.

Merry Codemas