Nhibernate query only properties and many-to-one

1
 

If you does not know Query only properties of NHibernate you better take a look to this post, I must admit that they are really useful to make simpler query without changing the object model. I’ve this object model

image

This is how the domain was build, we decided to set a IList<DomainRegistrations> in the NickName class, and make this relation unidirectional. Now I need to issue a query to recover only Id and Url of all NickNameDomainRegistration object belonging to a certain NickName.

The obvious solution is, Load the NickName fetching NickNameDomainRegistration, then grab the information you need. But I do not like this approach, because the Note field can be really long, and I do not want fetching unnecessary data from database. Moreover I have index on database on Id, Url, and the foreign key to nick name, so I really want to issue a projection that only query those fields. The structure of the project is based on ICriteria for issuing query, and I want a simple way to express the query. Thanks to Query only properties I can add this line to the mapping of NickNameDomainRegistration

1
2
<many-to-one name="NickName" access="none" class="NickName" column="budr_buniId" />
 

Thanks to the access=none I can tell nhibernate that NickNameDomainRegistration has a property of type NickName even if the POCO object does not have it. Now I can issue a query for NickNameDomainRegistration with a  condition of NickName.Id == id. Everything works fine, but running the whole set of unit test I noticed that some other test has failed.

Examining the tests, I found that association to NickNameDomainRegistration is no more saved into the database. This is due to the fact, that now nhibernate think that the relation should be managed from the <many-to-one> part, even if the <set> in NickName is mapped as Inverse=true

The solution is changing the mapping, telling nhibernate that we really do not want the query only property to be used in insertion and update of the relation.

1
2
<many-to-one name="NickName" access="none" class="NickName" column="budr_buniId"
update="false" insert="false"  />

Now all of my tests passes again, and I look at generated query with NHProfiler.

image

I’m still having problem, because it issue a inner join on table BuzzNickName (the table that contains the NickName entity) that is unnecessary, because no field of NickName is nor needed nor used in the filter. To obtain a real good query you need to add another query only property with this definition.

1
2
<property name="NickNameId" access="none" column="budr_buniId" type="System.Guid"
insert="false" update="false" />

Now I can use the NickName property if I need to filter for some property of NickName (ES, NickName.Name == xxx) but I use the NickNameId property to filter for owner NickName. This will produce the query.

image

That is the query I want.

Alk.