NHibernate Query Generator - More Collections Magic
I wouldn't have expected it to be this hard*, but it is alive!
Here is the query:
1: User one = User.FindOne(
2: Where.User.Blogs
3: .With(JoinType.InnerJoin)
4: .Name == "Ayende @ Blog"
5: );
And the generated SQL:
1: SELECT
2: this_.Id as Id4_1_,
3: this_.Name as Name4_1_,
4: this_.Email as Email4_1_,
5: blog1_.Id as Id3_0_,
6: blog1_.Name as Name3_0_,
7: blog1_.Author as Author3_0_
8: FROM Users this_ inner join Blogs blog1_
9: on this_.Id=blog1_.Author
10: WHERE blog1_.Name = @p0
And, because Rob has asked, here is how you do a more complex query, over Many To Many association:
1: User one = User.FindOne(
2: Where.User.Name == "Ayende" &&
3: Where.User.Roles.With().Name == "Administrator"
4: );
And the generated SQL:
1: SELECT this_.Id as Id0_1_,
2: this_.Name as Name0_1_,
3: this_.Email as Email0_1_,
4: roles3_.UserId as UserId__,
5: role1_.Id as RoleId,
6: role1_.Id as Id9_0_,
7: role1_.Name as Name9_0_
8: FROM Users this_ inner join UsersRoles roles3_
9: on this_.Id=roles3_.UserId
10: inner join Roles role1_
11: on roles3_.RoleId=role1_.Id
12: WHERE this_.Name = @p0 and role1_.Name = @p1
It is in the repository now, but right now I would consider it beta stage, it works, but the generation will probably die if you have any sort of interesting schemas (specifically, if you have collections of value types, it is supposed to die horribly with confusing error message).
I intend to do a screen cast about this area of querying, searching and persistence soon.
* Right now code generation competes with template magic and three stars code in my internal dislike list. Trying to get the sort of syntax that you see about is really stretching C# to its limits. When can I get a Method Missing implementation on C#? That would actually make my life easier?
Comments
Wonderfull! Great Job Ayende!
I've found a little bug, the QueryBuilder.cs file is generated with the literal "namespace" attached to the generated namespace declaration:
namespace QueryNamespace
{
.....
.....
I should be replaced when you run the code, can you check it?
Line #113, program.cs
Great job Ayende, but I think I have a problem. I'm using ActiveRecord, I have a class CentroRecolector wich have a collection of objects of type Instrumento, but NHQG does not generate the necesary code to be able to write Where.CentroRecolector.Instrumentos.With nor Where.CentroRecolector.Instrumentos.Exists
Ok, with the latest version now it works! ;)
I love this syntax.
I tried to use the new With() to FetchMode.Eager a collection, but no luck (it was lazy). See my test for what I am hoping would work...
I took a look at the QueryBuilder and custom tool output and my head hurt, but what I was trying seemed to be within the realms of possibility.
Any tips?
// DetachedCriteria dc = DetachedCriteria.For<Application>();
// dc.Add(Expression.Eq("Id", new Guid("{DD635128-387B-46de-A850-F1F59FB4167F}")))
// .SetFetchMode("Operations", FetchMode.Eager);
// application = appDa.FindOne(dc);
Can we continue this discussion at rhino-tools-dev@googlegroups.com
I would like to get a full test case, one that I can run.
This was just what I was looking for when I emailed you recently asking whether NQG supports quering associations.
Thank you very much!
Christian
I like the ideas you show here, but how can an n00b get started on this?
I'm looking for starting points, and have tried the quickstart thingy for nhibernate so I have an class, mapping etc to get one row from an database.
But my "User" object does not have any FindOne method.., and I'm looking through the generated QueryBuilder.cs but cannot find anything that refers to my class, even if I fed it with my dll and mapping file..
Everything I read around on this things looks like it is suited for people who have been using nhiber etc for many years.. When I took up subsonic, that was very easy, generating classes with foreignkey support and everything.. but it lacks some serious functionality imho, like joins, and therefore I want to check out nhiber, but it gives me pain. so I was hoping the querygenerator and stuff could ease that, but not yet..
I even bought the book NHibernate in action from Kuate, but that is not easily grasped... yet..
And doesn't it exist any tool that can read the database, generate mappinfiles, and classes to avoid some of the DRY principles? at least for getting started, like reverseenginering in visio etc..so you don't need to type everything 3-4 times?
AsbjornM ,
There are levels of use in each platform. What I am showing here is meant for those that are already familiar with NHibernate and wants to take advantage of their knowledge in the best possible way.
For beginners ,there are numbers of avenues. There is a DNR TV episode that I did on NHibernate which may give you an idea about how to start, and there are numerous articles about it, including the book that you have mentioned.
The sample code that I have shown is using Active Record, which does give you an implementation of FindAll, FindOne, etc.
As for tools, you can check out Active Writer
Comment preview