我花了太多时间找到一个很好的方式来加载子集合。到目前为止,这就是我得到的。它有效,但我发现很难相信这是编写此查询的最佳方式
[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);
}
答案 0 :(得分:1)
我想追加不同的观点,而不是如何使用“未来”只进行一次往返DB的回答。
不确定为什么需要获取所有属性。我猜你的代码可能会使用1),例如将UI或2)渲染为API,以某种方式将其序列化并将其传递给客户端。
在第一个场景中,我建议每个请求使用会话并使用延迟加载。在第二步中,我建议引入一个步骤:在将DTO传递给客户端之前构建它。这可以在会话仍然打开时完成,因此使用延迟加载。
两种情况下的延迟加载。因此,在这两种情况下,我建议使用不同的方法然后显式提取。它将使用或多或少相同数量的选择和往返DB。但最终它可能会更有效。因为所有这些工作都将留在NHibernate上
事情是用批量大小(本机)加载来改变eager-fetch(手动)加载。点击此处查看19.1.5. Using batch fetching。在这种情况下,NHibernate将处理您的查询,然后将再次使用更多查询来加载剩余数据。但只有在真的需要时
优点是,您不是您的疑问的囚徒。您可以使用实体上可以/应该可用的任何属性,直到会话打开(即,在视图呈现或序列化期间)。您不必在连接上附加另一个显式查询以获取急切数据。
所以,虽然Future可能是世界的解决方案,但是你从APP连接数据库的速度非常慢......世界上并没有使用NHibernate(ORM)。惰性映射和临时加载(具有批处理功能)的优点是从维护角度来看正确...我会说