There are situations when you do not need to get the fully tracked entities using NHibernate — you know you wouldn’t ever edit them and need minimum overhead for this specific scenario. One example is AJAX auto-completion. On the other hand, if you are as obsessed with architectural purity as me, you probably do not have Id properties in your entities, since they are artefacts of (relational) DBs.

So there is the question: in UI layer we want to do

repository.Query().Select(x => new ListItem { Key = x.Id, Name = x.Name })

But there are no “Id” properties in our entities. How can we do this (without returning to the dark ages of untyped criteria)?

There is a very simple (and working) answer. Let’s start with how I do it for individual entities. When I need a key/id in the UI to identify the entity between requests, I use repository.GetKey(entity), which internally calls session.GetIdentifier(entity). Simple and not intrusive into domain logic. Now,

repository.Query().Select(x => new ListItem { Key = GetKey(x), Name = x.Name })

is obviously impossible, since HQL/DB can not understand GetKey call.

Ok, so the solution is to pre-process the call before Linq-to-NHibernate and replace GetKey call with reference to fake property named “id”, which is a magic name NHibernate understands as identifier reference. Linq-to-NHibernate even provides public expression visitor, so it was trivial to create KeyMethodToIdRewritingVisitor (the fake PropertyInfo took most effort, which had to have some stuff to fool Expression.Property).

You can get resulting code below.
It is not perfect, but it works and flaws are really easy to polish out.

  1. Repository
  2. KeyMethodToIdRewritingVisitor
  3. KeyEnabledQueryProvider

I wrote an article on Code Project about the way to implement generics in ITemplate.
I thought about including the whole article as a blog entry, but I am still fighting with code highlighting in blog.

Interesting fact about the Repeater solution is that you can use it to build any kind of generic asp.net control that will be perfectly specifiable in mark-up.
I am writing a GenericeControlBuilder that will not be specific to the single control type, but I didn’t have enough time to finish it yet.

The interesting question is how to implement fully generic TemplateContainerAttribute. Dynamic creation of the attribute is not a problem at all — solved in the article.
But the question is how to know right TemplateContainer type in a GenericControlBuilder that has no hardcoded information about the control it creates.
I consider adding another attribute that will specify how control type arguments map to the TemplateContainer type arguments.

public class Repeater {
    …

    [GenericTemplateContainer(typeof(RepeaterItem<>), UseParentTypeArguments=true)]
    public ITemplate ItemTemplate

    …
}

This is just to show the basic idea — this syntax is way too limiting.