NHibernate создает прокси через session.Load(), но не через Linq или Criteria API.

StackOverflow https://stackoverflow.com/questions/1643905

Вопрос

У меня странная проблема в моем текущем проекте.Ленивая загрузка запросов не работает.Когда я запрашиваю список, nhibernate извлекает все ассоциации отдельно.

Я извлек небольшие его части и поместил в отдельный раствор.По сути, сейчас у меня есть таблица учетных записей и таблица синхронизации учетных записей.Оба имеют идентификатор и URL-адрес, а идентификатор — это просто db-guid.

Мои занятия:

public class HippoAccount
{
    public virtual Guid Id { get; set; }
    public virtual string Url { get; set; }
    public virtual HippoAccountSync Sync { get; set; }
}

public class HippoAccountSync
{
    public virtual Guid Id { get; set; }

    public virtual string Url { get; set; }
    public virtual HippoAccount Account { get; set; }
}

Когда я теперь загружаю объект через его руководство:

var account = session.Load<HippoAccount>(accountId);
Console.WriteLine(NHibernateUtil.IsPropertyInitialized(account, "Sync"))

...он возвращается false и сама учетная запись является прокси.

Но при загрузке списка через API критериев:

var account = (HippoAccount)session
    .CreateCriteria(typeof (HippoAccount))
    .Add(Restrictions.Eq("Id", accountId))
    .List()[0];

...недвижимость Sync инициализируется (запускается второй запрос выбора), и возвращаемый объект не является прокси.

Это поведение по умолчанию?Что я делаю не так?

Отображение:

<class name="HippoAccount" table="AllAccounts">
  <id name="Id" type="guid">
    <generator class="guid"/>
  </id>
  <property name="Url" />

  <many-to-one 
           class="HippoAccountSync"
           name="Sync"
           not-found="ignore"
           property-ref="Url">
    <column name="url" />
  </many-to-one>
</class>

<class name="HippoAccountSync"
       mutable="false"
       table="Accounts">

  <id name="Id" type="guid">
    <generator class="guid"/>
  </id>

  <property name="Url">
    <column name="serviceUri" />
  </property>

  <many-to-one class="HippoAccount"
               name="Account"
               property-ref="Url"
               not-found="ignore">

    <column name="serviceUri" />
  </many-to-one>

</class>
Это было полезно?

Решение

После еще нескольких исследований я нашел ответы.Ответы, потому что есть много вещей, которые могут предотвратить отложенную загрузку в NHibernate.

  1. Запрос против.сеанс.Загрузка: При получении элемента через session.Load() вы получаете прокси.Но как только вы получите доступ любой собственность, скажем так Url, объект извлекается, включая все его ассоциации, которые не поддерживают отложенную загрузку.

  2. ссылка на свойство: Ленивая загрузка работает только с идентификатором объекта.Когда ассоциация свойств разрешается через другой столбец в целевой сущности, NH быстро извлекает ее. Не то чтобы это было невозможно, просто это не реализовано: Ошибка

  3. не найден = игнорировать позволяет неверный внешние ключи, то есть, если объект, на который ссылается, не найден, NH инициализирует свойство с нулевым значением.NH не перехватывает доступ к свойству для отложенной загрузки, а вместо этого назначает прокси-сервер объекта.С not-found="ignore" он не может решить, должно ли свойство быть установлено в значение null или прокси для данного, возможно, недействительного внешнего ключа. Эту проблему можно решить, перехватив доступ к собственности.

  4. При отключении not-found="ignore" и property-ref экспорт схемы создаст ограничения, обеспечивающие циклическую ссылку.Не хорошо!В этом случае правильным отображением будет ограниченное взаимно-однозначное отношение, где ключом к HippoAccountSync должен быть генератор foreign.

Ресурсы

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top