Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 5,954 | Comments: 44,412

filter by tags archive

Introducing the NHibernate Query Generator


Okay, it looks like I can track down fairly easily what books I read, when I read Working Effectively with Legacy Code, I wrote Rhino Mocks. Now I am reading Applying Domain-Driven Design and Patterns, and I wrote the NHibernate Query Generator.

So, what is this all about?

NHibernate has two major API for querying objects. The first one is called the query API, and uses HQL, a language similar to SQL but with OOP aspirations. The second is called the criteria API, and it is far simpler API, but it is also much easier to use.

Here is a simple example of using the criteria API using my Repository sample from yesterday:

ICollection<Customer> customersInLondon = Repository<Customer>.FindAll(Expression.Eq("City""London"));

Now, those of you that already knows me know that I have a passionate dislike to strings. I wrote a mock objects library because of this issue, so I may need physcological therapy in the future, but I hate strings.

Well, what do I do when there is something that I don't like? I fix it.

In this case, there where two main options, run time proxying and code generation.

Run time proxying is similar to what I do in Rhino Mocks, and it may look like this:

ICollection<Customer> customersInLondon = Repository<Customer>.FindAll(Expression.Eq(Expr.Of<Customer>().Name,"London"));

This has the disadvantages of being both ugly and complex, so I turned to the other route. I build a small application which takes an NHibernate mapping file (hbm.xml) file, and output a strongly typed query wrapper. The above query can now be used like this:

ICollection<Customer> customersInLondon = Repository<Customer>.FindAll(
   Where.Customer.City.Eq("London") );

This is much better, and of course that you get all the other nice things about the expression API (like Between, In, etc).

You can get it here, binaries only. Source would have to wait for a while, my subversion provider has run out of room. Note that the code it generates relies on a class called NamedExpression. The class is included in the binary, so just add it to your project and you are done.

I also added support for queries, since I didn't want to leave the other side of the API high and dry, it means that you can do this:

ICollection<Customer> customersInLondon = Repository<Customer>.FindAll(
    Queries.AllCustomersInCity, new Parameter("city""London"));

Here is a little FAQ

  • What does it generate:
    The tool generate strongly typed wrappers for each of the mapped entities and each of their properties. At the moment, is supports querying against properties, many-to-one, and ids.
  • How to make it work for all the files in a directory?
    Simply use the batch capabilities of the shell, like this:
    for %f in (*.hbm.xml) DO "NHibernate.Query.Generator.exe" %f D:\Queries
    This will run the tool over all the files in the directory, and output them all to the Queries dir.
  • How to make it work with ActiveRecord?
    You need to use the isDebug="true" flag in the configuration, and then point the tool to the resulting mapping files.
  • Can I get is as a custom tool for Visual Studio?
    It shouldn't be hard to do, but I don't have the time at the moment. Feel free to send me a patch for it when I release the code.

Comments

hdmsqxet

hdmsqxet

jxgcktia - Google Search

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. What is new in RavenDB 3.5–Intro - 18 hours from now

There are posts all the way to Jul 08, 2015

RECENT SERIES

  1. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
  2. Special Offer (2):
    27 May 2015 - 29% discount for all our products
  3. RavenDB Sharding (3):
    22 May 2015 - Adding a new shard to an existing cluster, splitting the shard
  4. Challenge (45):
    28 Apr 2015 - What is the meaning of this change?
  5. Interview question (2):
    30 Mar 2015 - fix the index
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats