Layerless: How I Learned to Stop Worrying and Love the IQueryable

In my last post repositories were made simpler and more descriptive. The central piece in this was the IQueryable. This interface is at the core of every Linq Provider. A Linq Provider is the machinery that will convert our linq statements in a format that is readable for the underlying datastore (e.g. sql, xpath,...). Using the IQueryable as the core of your data access strategy enables us to do some nifty things. In this post I will examine two of them: Composite Queries and Projections. In a next post I will show how these can be used to improve databinding in Webforms 4.5

Composite Queries

One of the more tricky elements of linq is the idea of deferred execution: a linq statement will only be executed when it is enumerated. This is the source of some subtle bugs, but also very powerful. This means we can chain several of the extension methods I talked about earlier together to create a composite query:

var result = Db.Query<User>()
               .OlderThan(9)
               .UserNameStartingWith("E");

Since the query will only be generated once the IQueryable is enumerated, the resulting query will be (SqlCE syntax):

select user0_.UserId as UserId0_, user0_.UserName as UserName0_, user0_.BirthDate as BirthDate0_
    from [User] user0_ 
    where (user0_.BirthDate is not null) and 
    dateadd(dd, 0, datediff(dd, 0, user0_.BirthDate)) and 
    (user0_.UserName like (?+'%E'))

This allows us to define fragmented queries that can be used to compose larger queries. This also allows for something pretty nice in Webforms 4.5.

Projections

Another lovely feature you get for free by using a modern ORM with a decent Linq Provider are projections. This basically means you’ll only select the fields from the database what you need. NHibernate has always had projections, but they were never easy to set up. The linq provider in NHibernate gives us a much nicer developer experience. For example this statement:

var result = Data.Select(u => u.UserName).ToList();

Will produce the following query:

select user0_.UserName as col_0_0_ from [User] user0_

So instead of the complete User object, we only get the fields we asked for. This is handy if we want to construct a Viewmodel for databinding and not the Entity. Using Viewmodels is also something that will make our life easier in the Webforms 4.5 world. So stay tuned for the next instalment of the Correlated Content blog – now in English.