How to create overly complex NHibernate queries?

by Mikael Henriksson 15. December 2009 16:06

If I had it my way we would probably have the whole darn thing in one and the same table but that would not work out long term. The problem I was facing was to fetch one entity based on values in the parent and 2 other (to the parent) related entities. Then I want to eagerly fetch information from the parent.

// Create criteria and add sorting based on version
var criteria = work.Session.CreateCriteria<ContactVersion>("v")
    .AddOrder(Order.Desc("v.Version"));

// Create restriction based on that the contact should:
// 1. Not be deleted and
// 2. Match the accountId
criteria.CreateCriteria("v.Contact", "c")
    .Add(Restrictions.IsNull("c.DeletedAt"))
    .Add(Restrictions.Eq("c.Id", accountId));

// Also add a restriction based on uid
criteria.CreateCriteria("c.Devices", "dc")
    .Add(Restrictions.Eq("dc.Id", uid));

// Lastly add a restriction for the current device id and
// eagerly fetch the corresponding contact.
criteria.CreateCriteria("dc.Device", "d")
    .Add(Restrictions.Eq("d.Id", deviceId))
    .SetFetchMode("c.Contact", FetchMode.Join)
    .SetFetchSize(1)
    .SetMaxResults(1);

var c = criteria.UniqueResult<ContactVersion>();

This gives me the desired result and the query looks like follows:

SELECT top 1 * /* removed all the columns */
FROM   contact_version this_
       inner join contact_def c1_
         on this_.contact_id = c1_.contact_id
       inner join contact_device_uid dc2_
         on c1_.contact_id = dc2_.contact_id
       inner join device_def d3_
         on dc2_.device_id = d3_.device_id
WHERE  this_.contact_version_ordinal = 3 /* @p0 */
       and c1_.dte_deleted is null
       and c1_.subscription_id = 4 /* @p1 */
       and dc2_.contact_uid = 1 /* @p2 */
       and d3_.device_id = 1 /* @p3 */

A quick look at the query execution plan shows nothing really strange so I suppose I sort of got it right. At least I got the data that I asked for..

Tags:

NHibernate

blog comments powered by Disqus