Projections Support In Active Record

time to read 8 min | 1548 words

Ken, this post if for you...

So, I have been a busy implementing crazy generics stuff and I can show you this:

public class ProjectionQuery<ARType> : ProjectionQuery<ARType, object[]>

Neat class, isn't it?

Please not that this is not the same class that I shows here, that class has been renamed ScalarProjectionQuery, since it better fits its duy.

What can you do with it? Well, things like this:

ProjectionQuery<Blog> proj = new ProjectionQuery<Blog>(
Projections.Property("Name"), Projections.Property("Author"));

IList<object[]> results = proj.Execute();

Assert.AreEqual(blog.Name, results[0][0]);

Assert.AreEqual(blog.Author, results[0][1]);

Now you have got a list or arrays, which contains just the Name and Author from the Blog entity. This used to be much harder and involved writing HQL code (which can be a bummer, since I insist on putting all the HQL code in the mapping files, and not concatenating HQL).

It still has a major issue for me, and that is the fact that I need to work with untyped arrays, not fun, and I simple hate to work with numeric indices. Therefor, let us try this version:

public class ProjectionQuery<ARType, TResultItem> : IActiveRecordQuery

What does this allows me to do? Well, you can write the above snippet of code as:

ProjectionQuery<Blog, KeyValuePair<string, string>> proj = new ProjectionQuery<Blog, KeyValuePair<string, string>>(

               Projections.Property("Name"), Projections.Property("Author"));

IList<KeyValuePair<string, string>> results = proj.Execute();  

Assert.AreEqual(blog.Name, results[0].Key);

Assert.AreEqual(blog.Author, results[0].Value);

Notice that we suddenly have a strongly typed (if generic) way of accessing the information. In fact, in this case, a small, dedicated, class is what I would use. So I could do this:

ProjectionQuery<Blog, NameAndAuthor> proj = new ProjectionQuery<Blog, NameAndAuthor>(

                           Projections.Property("Name"), Projections.Property("Author"));

IList<NameAndAuthor> results = proj.Execute();

Assert.AreEqual(blog.Name, results[0].Name);

Assert.AreEqual(blog.Author, results[0].Author);

Much, much, nicer, in my opinion. :-)

And yes, there is more suprises in the pipeline :-)