2016-05-09 3 views
1

У меня есть метод, который извлекает Entity из базы данных с помощью nHibernate. Это довольно сложный Entity:Почему nHibernate ленивая загрузка и игнорирование результатов будущего запроса?

Level4 имеет много Level3s, которые имеют много Level2s, которые имеют много Level1s ​​которых имеет Level1Ref

Поэтому я использую несколько фьючерсы, как это:

 var future = this.Session.QueryOver<Level4>() 
      .Where(x => x.Id == level4Id) 
      .Fetch(x => x.Level3List).Eager 
      .Fetch(x => x.Level3List.First().Level2List).Eager 
      .Left.JoinAlias(x => x.Level3List,() => level3Alias, x => x.AnotherThing.Id == anotherThingId) 
      .FutureValue(); 

И некоторые запросы, как это:

 this.Session.QueryOver<Level1>() 
      .Fetch(x => x).Eager 
      .Fetch(x => x.Level1Ref).Eager 
      .Fetch(x => x.Level2).Eager 
      .Inner.JoinAlias(x => x.Level2,() => level2Alias) 
      .Inner.JoinAlias(() => level2Alias.Level3,() => level3Alias, x => x.AnotherThing.Id == anotherThingId && level3Alias.Level4.Id == level4Id) 
      .Future(); 

А потом:

var record = future.Value; 

Все это генерирует SQL, которого я ожидал бы, но когда я пытаюсь выполнить итерацию над Level2.Level1List, он ленив загружает записи в этот список.

Вопрос:

Это проблема. Что я? в моем запросе неверно, что nHibernate думает, что ему нужно перейти в базу данных для получения информации, которую она уже получила? (У меня есть подозрение, что мне нужно поменять некоторые из моих JoinQueryOver бит для нетерпеливых разгонов?

(Вопросы отредактированы упростить примеры)

+0

Я думаю, что ваша догадка правильная. 'Future' предназначен для отсрочки выполнения (обычно) пакета запросов, так что в базу данных есть только одна обратная связь. «Fetch» ​​- это то, что вам нужно - он может загружать связанные объекты вместе. Тем не менее, по моему опыту, он получает ошибку для более чем двух уровней выборки. –

+0

По моему опыту, NHibernate не очень силен в нетерпении. Обычно я полагаюсь на ленивую загрузку, которая может работать очень хорошо, если правильно [настроена] (/ a/36070727/1178314). –

+0

Спасибо @ Frédéric. Цель для нас - поразить базу данных в кратчайшие сроки, поэтому ленивая загрузка - это не то, что нам нужно. – Adam

ответ

1

После большого исследования единственным способом, которым я мог бы получить эту работу была изменение все мои вопросы, так что они имеют один и тот же TRoot Т.е. изменить их так, все они начинаются так:..

this.Session.QueryOver<Level4>() 

это, очевидно, не является идеальным в таких ситуациях:

рыботорговца

Коллекция рыб

Коллекция глаз Коллекция костей

Это означает, что я должен написать два запроса и присоединиться рыбы дважды ...

Альтернативой является ленивая загрузка и пакетная обработка запросов, Требование состоит в том, чтобы сделать только одну поездку туда и обратно в базу данных.

Смежные вопросы