Ленивая загрузка эталонного объекта
У меня есть этот сценарий:
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-строки. Это как ленивая загрузка не работает.
Мои вопросы:
- Как мне заставить работать ленивец?
- Можно ли объединить объекты 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), но, возможно, вы можете найти некоторый пример кода.