Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to access a field of type discriminator in NHibernate

I have a class base on my map, it inherited two new classes

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Business" namespace="Business.Test">
<class name="BaseExample" table="base_example" abstract="true" discriminator-value="0">
    <id name="Id" column="id" type="Int64" unsaved-value="0">
        <generator class="native"/>
    </id>
    <discriminator column="domain" type="Int16" not-null="true" force="true" />
    ....
    ....
</class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Business"   namespace="Business.Test">

<subclass name="Example1" extends="BaseExample" discriminator-value="1">
....
....
</subclass>
</hibernate-mapping>

everything works fine, but if I ask for that field, for example:

var Clients = ClientFactory.GetAll().Where(c => c.UserData.BaseExample.Domain == 1);

throw this exception: Exception Message: could not resolve property: Domain of: Business.Entities.BaseExample

how can tell if it is of one class or another?

like image 613
TlonXP Avatar asked Jan 17 '23 08:01

TlonXP


2 Answers

Discriminators are meant to be used behind-the-scenes from NHibernate (see Rippo's example). The idea is that you query the class and the appropriate discriminator from that class's mapping is injected into the query.

However, if for some reason you need that information in a property it is valid to include it as a property. That means

<class name="BaseExample" table="base_example" abstract="true" discriminator-value="0">
    <id name="Id" column="id" type="Int64" unsaved-value="0">
        <generator class="native"/>
    </id>
    <discriminator column="domain" type="Int16" not-null="true" force="true" />
    <property name="domain" column="domain" type="Int16" update="false" insert="false" />
    ....
    ....
</class>

it is important that you declare the property as readonly (update="false" insert="false") since this is a column managed completely by nhibernate.

like image 64
Jaguar Avatar answered Feb 03 '23 21:02

Jaguar


Using QueryOver to get all records in the base_example table for class BaseExample you would do this:-

session.QueryOver<BaseExample>().List();

to get all Example1 records you would do this

session.QueryOver<Example1>().List();

to get all Example2 records:-

session.QueryOver<Example2>().List();

In other words NHibernate is clever enough to add the where clause Domain=1 or Domain=2 in the query for you automatically.

Also it should be noted if you want all the records from the base table and have a loop, then you could do this:-

var list = session.QueryOver<BaseExample>().List();
foreach(var item in list) {
  if (item is Example1)
    Output(Example1) //Do something with Example1
  if (item is Example2)
    Output(Example2) //Do something with Example2
} 
like image 25
Rippo Avatar answered Feb 03 '23 21:02

Rippo