Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query by discriminator in NHibernate

Tags:

c#

nhibernate

I did some searching on this and didn't turn up anything. Is it possible to create a Hibernate query to return a set of objects based on a discriminator?

I have an AbstractUser class which is extended by the concrete classes UserTypeA and UserTypeB. I'm using the table-per-hierarchy model to map my classes in NHibernate, so UserTypeA and UserTypeB are both stored in the same table with different discriminator values. Here is my discriminator mapping property:

<discriminator column="Type" type="string"/>

I have a column in my table that contains the name of the user type. I'm wondering if it's possible to run a NHibernate query using this.

I tried this:

public IList<DomainBase> FindByType(string typeName, Type type)
{
    string query = "from " + type.Name + " k where k.Type = " + typeName;
    return Session.CreateQuery(query).List<DomainBase>();
}

But since Type is not actually a property of the class, just a column in the table, this obviously doesn't work. It would seem redundant to have both a property for this purpose and a discriminator, unless there's a way to use a property as a discriminator?

like image 742
Tyler Treat Avatar asked Jan 17 '11 00:01

Tyler Treat


2 Answers

Actually, this is well documented at http://www.nhibernate.info/doc/nh/en/index.html#queryhql-where:

Likewise, the special property class accesses the discriminator value of an instance in the case of polymorphic persistence. A .Net class name embedded in the where clause will be translated to its discriminator value.

 from Eg.Cat cat where cat.class = Eg.DomesticCat

You can also pass a System.Type instance as a parameter.

like image 119
Diego Mijelshon Avatar answered Nov 19 '22 08:11

Diego Mijelshon


If you really only want to query on the type, then I think using the ICriteria API is a more convenient option:

public IList<T> FindByType<T>()
{
    return Session.CreateCriteria(typeof(T)).List<T>();
}

Now you can use it like IList<UserTypeB> list = FindByType<UserTypeB>().

like image 25
Elian Ebbing Avatar answered Nov 19 '22 08:11

Elian Ebbing