Layerless: How I Learned to Stop Worrying and Love the IQueryable
14 juni, 2012In 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.