Ленивая загрузка эталонного объекта

У меня есть этот сценарий:

class A
{
    public virtual int Id { get; set; }
    public virtual B Child { get; set; }
}

class B
{
    public virtual int Id { get; set; }
}

В отображении класса A у меня есть ссылка на класс B:

map.Reference(a => a.Child).LazyLoad();

Теперь, когда я делаю что-то вроде:

Session.Query<TypeOfA>().Select(a => a);

Помимо обычного выбора * из ATable, я получаю n выборок из BTable для каждой A-строки. Это как ленивая загрузка не работает.

Мои вопросы:

  1. Как мне заставить работать ленивец?
  2. Можно ли объединить объекты A и B в одном запросе?

Спасибо,

2 ответа

Решение

Ленивая загрузка включена по умолчанию и на самом деле должна работать. Если возникнет проблема, например, если он не сможет сгенерировать прокси для класса B, он будет жаловаться при создании фабрики сеансов.

Вы уверены, что запросы для B выполняются самим запросом, а не последующим доступом к A?

Вы можете оптимизировать доступ к B двумя способами: получить их вместе с A в одном запросе. (Я не знаю бегло, это способ XML это настроить:)

<many-to-one fetch="join" ...>

Это имеет некоторые проблемы при использовании со списками и может также сильно взорвать ваш запрос. Это, конечно, не ленивая загрузка вообще.

Другая, очень приятная и мощная оптимизация - пакетная загрузка. Он позволяет извлекать экземпляры в отдельных запросах, но выбирает сразу несколько из них.

<class name="B" batch-size="20" ...>

Это принесло бы 20 B одновременно в одном запросе. Он также доступен для списков:

<one-to-many fetch-size="20" ...>

В дополнение к предложению Stafan использовать пакетный размер, быстрый поиск в Google показывает, что Fluent NHibernate теперь поддерживает BatchSize для запросов. Из документов:

ClassMap<T> BatchSize(int size) 

Sets the query batch size for this entity.

Никогда не использовал его сам, и документация минимальна (как много FNH), но, возможно, вы можете найти некоторый пример кода.

Другие вопросы по тегам