Попытка получить доступ к полю дискриминатора типа в NHibernate - PullRequest
4 голосов
/ 02 марта 2012

У меня есть база классов на карте, она унаследовала два новых класса

<?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>

все работает нормально, но если я запрашиваю это поле, например:

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

выбросить это исключение: Сообщение об исключении: не удалось разрешить свойство: Домен: Business.Entities.BaseExample

как узнать, принадлежит ли он к тому или иному классу?

Ответы [ 2 ]

8 голосов
/ 02 марта 2012

Дискриминаторы предназначены для использования за кулисами из NHibernate (см. Пример Rippo). Идея состоит в том, что вы запрашиваете класс , и соответствующий дискриминатор из сопоставления этого класса вводится в запрос.

Однако, если по какой-либо причине вам нужна эта информация в свойстве, ее можно включить в качестве имущества. Это значит

<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>

важно объявить свойство как только для чтения (update="false" insert="false"), поскольку этот столбец полностью управляется nhibernate.

1 голос
/ 02 марта 2012

Используя QueryOver, чтобы получить все записи в таблице base_example для класса BaseExample, вы должны сделать это: -

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

чтобы получить все Example1 записей, вы бы сделали это

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

чтобы получить все Example2 записи: -

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

Другими словами, NHibernate достаточно умен, чтобы автоматически добавлять предложение where Domain=1 или Domain=2 в запрос.

Также следует отметить, что если вы хотите, чтобы все записи из базовой таблицы имели цикл, то вы можете сделать это: -

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
} 
...