Как управлять многоуровневой иерархией классов в nhibernate со стратегией иерархии таблиц классов? - PullRequest
1 голос
/ 25 июня 2009

Я пытаюсь реализовать мою иерархию объектов в одной таблице с помощью стратегии «таблица на иерархию классов» в NHibernate. Я получаю сообщение об ошибке с моим отображением NHibernate, которое можно легко воспроизвести на простом примере. Ошибка:

System.NotSupportedException: Attempting to parse a null value into an sql string (column:activity0_.Type).
at NHibernate.SqlCommand.InFragment.ToFragmentString() in InFragment.cs: line 109
at NHibernate.Persister.Entity.SingleTableEntityPersister.DiscriminatorFilterFragment(String alias) in SingleTableEntityPersister.cs: line 551

Я могу воспроизвести это со следующими классами домена:

public interface IActivity
{
    Guid Id { get; set; }
}

public abstract class Activity : IActivity
{
    public DateTime StartTime { get; set; }
    public Guid Id { get; set; }
}

public class Running : Activity
{
    public string Where { get; set; }
}

public class Talking : Activity
{
    public string ToWhom { get; set; }
}

И следующее сопоставление XML:

<?xml version="1.0" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="NHibernateTesting"
                   namespace="NHibernateTesting" >
  <class name="IActivity"
         lazy="false"
         table="Activity"
         discriminator-value="0"
         abstract="true">
    <id name="Id">
      <generator class="guid" />
    </id>
    <discriminator column="Type" type="Int16" />
    <subclass name="Activity"
              discriminator-value="1"
              abstract="true"
              lazy="false">
      <property name="StartTime" />
    </subclass>
    <subclass name="Running"
              discriminator-value="2"
              lazy="false"
              extends="Activity">
      <property name="Where" />
    </subclass>
    <subclass name="Talking"
              discriminator-value="3"
              lazy="false"
              extends="Activity">
     <property name="ToWhom" />
    </subclass>
  </class>
</hibernate-mapping>

Кто-нибудь имеет представление о том, что я делаю неправильно?

Ответы [ 2 ]

5 голосов
/ 28 июня 2009

Я не очень знаком с c # и NHibernate, но вы уверены, что Activity должен быть установлен как abstract="true" в отображении?Похоже, класс Activity не является абстрактным.

Не должен Running и Talking находиться внутри Activity, иначе StartTime не будет сохранен.Правильно?

<subclass name="Activity"
...
  <subclass name="Running"
  ...
  </subclass>
  <subclass name="Talking"
  ...
  </subclass>
...
</subclass>

В любом случае сообщение об ошибке предполагает, что NHibernate пытается создать какой-либо запрос с оператором in-Statement.Но для этого нет никаких ценностей.Обычно он пытается создать что-то вроде

...
WHERE foo IN (null)

Если я правильно проанализировал код.Что вы пытаетесь сделать, когда попадание выдает эту ошибку?

Вы уже пытались включить их в hibernate-конфигурации, чтобы проверить, что происходит?

<property name="show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
2 голосов
/ 25 июня 2009

afaik Таблица на класс означает, что вы получаете таблицу в БД на класс, с 1-1 FK от родительской таблицы до наследования таблиц. Тогда не нужно дискриминаторов. Вам также не нужно отображать IActivity (если вы не намерены сеансы работать непосредственно против него; тогда потребуется некоторая настройка).

В любом случае, я настоятельно рекомендую вам взглянуть на FluentNHibernate, который делает отображение очень простым и имеет очень полезные значения по умолчанию для отображения 80% практически без кода.

...