Как избежать объединения с использованием NHibernate 2.1 для таблицы наследования - PullRequest
1 голос
/ 26 августа 2009

Я делаю по наследству некоторые таблицы, и все работает отлично, но я замечаю, что когда я хочу базовую сущность (данные базовой таблицы), NHProf показывает левое внешнее соединение дочерней сущности / (связанная таблица)

Как настроить поведение по умолчанию для запроса только необходимых данных, например: когда я хочу получить список родительских элементов (и только эти данные), запрос возвращает мне только этот элемент.

сейчас мое отображение похоже на следующее:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="FormBase, ClassLibrary1" table="tbl_FormBase">
    <id name="BaseID" column="ID" type="Int32" unsaved-value="0">
      <generator class="native" />
    </id>
    <property name="ImportDate" column="ImportDate" type="datetime" not-null="false" />
    <joined-subclass table="tbl_Form" name="Form, ClassLibrary1">
      <key column="ID"/>
      <property name="gendate" column="gendate" type="string" not-null="false" />
    </joined-subclass>
  </class>
</hibernate-mapping>

И пример, где я хочу вернуть все данные против ТОЛЬКО родительской сущности, показан ниже:

    Dim r As New FormRepository()
    Dim forms As List(Of Form) = r.GetFormCollection().ToList()



    Dim fbr As New FormBaseRepository()
    Dim fb As List(Of FormBase) = fbr.GetFormBaseCollection().ToList()

1 Ответ

2 голосов
/ 26 августа 2009

Вы не можете. Он называется «неявный полиморфизм», и это довольно приятная (хотя и нежелательная в вашем случае :-)) функция, предоставляемая Hibernate. Когда вы запрашиваете список базовых объектов, фактические возвращаемые экземпляры имеют фактические конкретные реализации. Следовательно, левое соединение необходимо для Hibernate, чтобы выяснить, является ли конкретная сущность FormBase или Form.

Обновление (слишком большой, чтобы поместиться в комментарии): Общая проблема здесь заключается в том, что если вы обманули Hibernate, чтобы загружать только базовую сущность, вы можете получить несовместимое состояние сеанса. Учтите следующее:

  1. Form (который сохраняется в таблицах form_base и form) был каким-то образом загружен как FormBase.
  2. Вы удалили его.
  3. Во время сброса Hibernate (который думает, что мы имеем дело с FormBase и, следовательно, блаженно не подозревает, что задействованы 2 таблицы), выдает оператор DELETE FROM form, который выдает исключение при нарушении FK.

Неявный полиморфизм существует, чтобы предотвратить это - Form - это всегда a Form, а не FormBase. Конечно, вы можете использовать отображение «таблица на иерархию», где все находится в одной таблице и, следовательно, не требуется никаких объединений, но вы в конечном итоге получите (потенциально) множество столбцов NULL и - ergo - неспособность указать not-null на детские свойства.

Все это говорит о том, что, если это REALLY огромная проблема для вас (чего обычно не должно быть - предположительно, это индексированное соединение), вы можете попробовать использовать собственный запрос, чтобы просто вернуть FormBase экземпляров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...