2012-03-02 1 views
4

У меня есть класс базы на моей карте, он унаследовал два новых классаПопытка получить доступ к полю типа дискриминатора в NHibernate

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

, как можно сказать, если это того или иного класса?

ответ

8

Дискриминаторы предназначены для использования за кадром из 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

Также на вашем классе я бы включил: - 'public int Domain {get; защищенный набор;} ' – Rippo

+0

, который был бы полезен, если вы хотите, чтобы он был видимым в коде приложения, но не требуется, если вы хотите его только для запросов. – Jaguar

+0

Вам нужен сеттер для полностью отображаемого свойства? – Rippo

1

Использование 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 
}