Когда вы выполняете будущий запрос, вы помещаете все родительские и дочерние объекты в кэш 1-го уровня.Родительские объекты содержат ленивую коллекцию, которую необходимо заполнить.Чтобы заполнить коллекцию, NHibernate должен запросить базу данных.(Мы выясним, почему всего за секунду.) Запрос возвращает дочерние объекты, и эти дочерние объекты уже находятся в кэше L1.Таким образом, эти объекты используются для заполнения коллекции.
Теперь, почему NHibernate вынужден запрашивать базу данных для заполнения коллекции Childs?В коллекции может быть предложение where, отфильтровывающее дочерние объекты с IsDeleted == true.Вы можете иметь код в EventListener, который отфильтровывает определенные дочерние объекты.По сути, многое может произойти, и NHibernate не может делать какие-либо предположения об отношениях между родительским и дочерним объектами.
Вы можете предоставить ему достаточно информации, указав стратегию выборки в HQL или в вашем отображении.В HQL вы могли бы написать:
var parents = session.CreateQuery("from Parent p join fetch p.Childs").Future<Parent>();
Запрос объекта Child, использующий будущее, будет совершенно необязательным, так как вы выбираете детей с родителями.Из-за выборки соединения вы получите дубликаты родительских объектов, хотя они будут одним и тем же объектом.(Вы выполняете внутреннее объединение в базе данных и возвращаете одну копию родительской строки для каждой дочерней строки.) Вы можете избавиться от них, перебирая parent.Distinct ().
Если вы всегда хотитечтобы получить дочерние объекты с соответствующим родительским объектом, вы также можете использовать fetch = "join" в вашем родительском отображении.
<bag name="Children" cascade="all-delete-orphan" fetch="join">
<key column="ParentId"/>
<one-to-many class="Child"/>
</bag>
Если ни один из этих параметров не подходит для вашего сценария, вы можете указать размер пакета всоставление карт.Вы по-прежнему будете выполнять запрос к базе данных, когда нажмете parent.Childs, но NHibernate с радостью инициализирует любые другие прокси-серверы коллекции.
<bag name="Children" cascade="all-delete-orphan" batch-size="10">
<key column="ParentId"/>
<one-to-many class="Child"/>
</bag>