Это правильный способ загружать дочерние коллекции в NHibernate?
Я потратил слишком много времени, чтобы найти хороший способ загружать дочерние коллекции. пока это то, что я получил. Это работает, но мне трудно поверить, что это лучший способ написать этот запрос
[Fact]
public void EagerLoadQueryOverWithFutureTest()
{
const long journalNr = 1470;
var query = _repo.QueryOver().Where(s => s.JournalNr == journalNr).Future<Sag>();
var sagsansoegning = _repo.QueryOver().Where(an => an.JournalNr == journalNr).Fetch(x => x.Sagsansoegning).Eager.Future<Sag>();
var noter = _repo.QueryOver().Where(n => n.JournalNr == journalNr).Fetch(x => x.Noter).Eager.Future<Sag>();
var filer = _repo.QueryOver().Where(f => f.JournalNr == journalNr).Fetch(x => x.Filer).Eager.Future<Sag>();
var emails = _repo.QueryOver().Where(e => e.JournalNr == journalNr).Fetch(x => x.Emails).Eager.Future<Sag>();
var journal = _repo.QueryOver().Where(j => j.JournalNr == journalNr).Fetch(x => x.Journal).Eager.Future<Sag>();
var sagsTilstand = _repo.QueryOver().Where(t => t.JournalNr == journalNr).Fetch(x => x.Tilstand).Eager.Future<Sag>();
var boligsocialEvalueringer = _repo.QueryOver().Where(b => b.JournalNr == journalNr).Fetch(x => x.BoligsocialEvaluering).Eager.Future<Sag>();
var result = query.SingleOrDefault();
result.JournalNr.Should().Be(journalNr);
result.Emails.Should().HaveCount(c => c > 20);
result.Filer.Should().HaveCount(c => c > 20);
}
1 ответ
Я хотел бы добавить другую точку зрения, а не ответ о том, как использовать "будущее", чтобы совершить всего лишь одну обратную поездку в БД.
Не уверен, почему вам нужно получить все свойства. Я предполагаю, что это может быть 1) для использования вашим кодом, например, для визуализации пользовательского интерфейса или 2) в качестве API, который каким-то образом сериализует это и передает его клиенту.
В первом сценарии я бы предложил использовать сеанс для каждого запроса и использовать ленивую загрузку. Во втором я бы предложил ввести один шаг: построить DTO перед передачей его клиенту. Это можно сделать, пока сессия еще открыта, поэтому используйте ленивую загрузку.
Ленивая загрузка в обоих сценариях. Итак, в обоих случаях я бы предложил использовать другой подход, чем явное извлечение. Он будет использовать более или менее одинаковое количество операций выбора и возврата в БД. Но в конце это может быть более эффективным. Потому что вся эта работа останется на NHibernate
Дело в том, чтобы изменить загрузку eager-fetch (вручную) с загрузкой размера пакета (native). Подробнее здесь 19.1.5. Использование пакетной выборки. В этом случае NHibernate обработает ваш запрос, а затем снова отправит еще несколько запросов для загрузки оставшихся данных. Но только если действительно нужно
Преимущество в том, что вы не являетесь узником ваших запросов. Вы можете использовать любое свойство, которое может / должно быть доступно на объекте, до тех пор, пока сеанс не будет открыт (т.е. во время рендеринга или сериализации View). Вам не нужно идти и добавлять другой явный запрос к соединению, чтобы получить нетерпеливые данные.
Таким образом, хотя Future может стать решением для всего мира, если ваше подключение к БД из APP очень медленное... это не тот мир, в котором нужно было использовать NHibernate (ORM). Преимущество ленивого картирования и специальной загрузки (с возможностью пакетной обработки) заключается в правильном подходе к техническому обслуживанию... Я бы сказал,