Почему мой дискриминатор возвращается как прокси? - PullRequest
1 голос
/ 18 августа 2011

У меня есть свойство Status в одном из моих POCO, которое действует как дискриминатор (очень похоже на использование enum).

Вот часть HBM, которая имеет столбец Status.

<many-to-one class="Locate.Common.Domain.Statuses.Status, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Status">
  <column name="Status_id" not-null="true" />
</many-to-one>

А вот мой HBM для таблицы Status.

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Locate.Common.Domain.Statuses.Status, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Status`">
    <id access="nosetter.lowercase-underscore" name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Status_id" />
      <generator class="assigned" />
    </id>
    <discriminator type="String">
      <column name="Status_id" />
    </discriminator>
    <property access="nosetter.lowercase-underscore" name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" not-null="true" />
    </property>
    <property access="nosetter.camelcase-underscore" name="IsUserSelectable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="IsUserSelectable" not-null="true" />
    </property>
    <subclass name="Locate.Common.Domain.Statuses.CallbackStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="3" />
    <subclass name="Locate.Common.Domain.Statuses.EmergencyStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="5" />
    <subclass name="Locate.Common.Domain.Statuses.FirstCheckerStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="1" />
    <subclass name="Locate.Common.Domain.Statuses.PleaseAdviseStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="4" />
    <subclass name="Locate.Common.Domain.Statuses.SecondCheckerStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="2" />
  </class>
</hibernate-mapping>

Наконец, вот мой QueryOver.

var locates =
    session.QueryOver(() => locateAlias)
    .SelectList(x => x
        .Select(xx => xx.WorkToBeginDateTime).WithAlias(() => sentTo.DueDate)
        .Select(xx => xx.SendTo).WithAlias(() => sentTo.SentTo)
        .Select(xx => xx.TicketNo).WithAlias(() => sentTo.TicketNo)
        .Select(xx => xx.Status).WithAlias(() => sentTo.Status)
    )
    .JoinAlias(() => locateAlias.Status, () => statusAlias)
    .Where(() => locateAlias.IsComplete == false)
    .TransformUsing(Transformers.AliasToBean<SentToDto>()).List<SentToDto>();

Thisзапрос выполняется без ошибок, однако свойство Status не инициализируется должным образом.Когда я использую значение Status, я получаю это исключение.

Initializing[Locate.Common.Domain.Statuses.Status#2]-Could not initialize proxy - no Session.

Глядя на профилировщик NHibernate, я вижу, что на самом деле он выбирает Status_id.

Что со мной не так, HBM или запрос?

Обратите внимание, что я успешно могу запрашивать все статусы и получать список всех объектов распознавания статуса.Я также вижу, что созданный прокси-объект содержит правильные значения объекта Status, поэтому NHibernate правильно возвращает правильные значения.

1 Ответ

3 голосов
/ 19 августа 2011

ваш запрос не Eeger-получить свойство Status и позже, когда вы обращаетесь к Status, сеанс, с которым вы загрузили локации, уже закрыт. Поэтому вместо .JoinAlias(() => locateAlias.Status, () => statusAlias) используйте .Fetch(locate => locate.Status).Eager

Редактировать: я подтвердил, это из-за выбора, что статус не с нетерпением извлекается. Это только нетерпеливое извлечение, если объект locate возвращается. Вы могли бы сделать:

var locates =
    session.QueryOver(() => locateAlias)
    .Where(() => locateAlias.IsComplete == false)
    .Fetch(locate => locate.Status).Eager
    .ToEnumerable()
    .Select(locate => new SentToDto
    {
        DueDate = locate.WorkToBeginDateTime,
        SendTo = locate.SendTo,
        TicketNo = locate.TicketNo,
        Status = locate.Status,
    }.ToList();
...