views:

44

answers:

2

I have two classes: Cat and DomesticCat, that extends Cat.

I want to select all Cats, but no oneDomesticCat. How to do it using NHibernate criteria API?

A: 

well it depends on the implementation.

If for example, you have a discriminator column (lets say <discriminator column="CatType" type="string"/> and the DomesticCat inheritor class discriminates with value "domestic") you could make an query like this

var allCatsButDomestic = nhSes.CreateQuery("from Cat c where c.CatType <> :catType")
     .SetString("catType", "domestic")
     .List<Cat>();

(in this particular example the Cat abstract class also maps the CatType column to a CatType string property)

EDIT and in Criteria form

var nonDomesticCats = session.CreateCriteria<Cat>()
                             .Add(Restrictions.Not(Restrictions.Eq("CatType", "domestic")))
                             .List<Cat>();

your comment about AnotherCat again implies that there is some way of discriminating between entities at the db level.

Jaguar
This is HQL, and it strictly depends on hierarchy. And what about if `AnotherCat` is derived from `DomesticCat`. I need to select only `Cat`s, your query says: select all, except `DomesticCat`.
SergeanT
+1  A: 
var nonDomesticCats = session.CreateCriteria<Cat>()
                             .Add(Restrictions.Eq("class", typeof(Cat)))
                             .List<Cat>();

class is a pseudo-property that represents the concrete type of entities in a class hierarchy.

It can be used transparently with any inheritance strategy except implicit.

Diego Mijelshon
Thanks a lot, I've found this solution yet :) it works +1
SergeanT
A class name embedded in the `where` clause will be **translated to its discriminator value** - says Hibernate documentation.
SergeanT
It's translated to a discriminator value when using table-per-clas-hierarchy, and to the corresponding internal case-statement values when using table-per-class or table-per-concrete-class.
Diego Mijelshon