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

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

Я извлек из него небольшие части и поместил в отдельный раствор. По сути, сейчас у меня есть Account-Table и AccountSync-Table. У обоих есть идентификатор и 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; }
}

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

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>

person Lars Corneliussen    schedule 29.10.2009    source источник
comment
не уверен, что это полностью связано, но есть проблемы с not-found = ignore: nhjira.koah. net / browse / NH-1001 guildsocial.web703.discountasp.net/dasblogce/   -  person Mauricio Scheffer    schedule 29.10.2009
comment
Ты прав. Еще одна проблема - свойство-ref - оно также отключает ленивую загрузку. maonet.wordpress.com/2007/12/05/   -  person Lars Corneliussen    schedule 30.10.2009


Ответы (1)


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

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

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

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

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

Ресурсы

person Lars Corneliussen    schedule 30.10.2009
comment
С помощью session.Load () вы, конечно, можете безопасно получить доступ к свойству Id прокси, не обращаясь к базе данных, поскольку вы дали прокси-серверу идентификатор для начала. - person Jay; 14.09.2010
comment
ссылка на ошибку property-ref больше не существует, ошибка 404. Есть идеи об этом прогрессе? - person shanabus; 26.04.2011