我想缓存一个永远不会改变的聚合,只能通过根对象访问(所有其他实体只能通过使用根对象上的Reference / HasMany属性访问)?
我应该使用NHibernate(我们已经在使用)二级缓存还是更好地构建某种单例来提供对聚合中所有实体的访问?
我发现了一篇关于使用MultiQuery
获取所有内容的博文,但我的数据库不支持它。
这样做的“老方法”是
类似的东西:
foreach (var e in Entities)
{
e.Parent = loadedParentEntities.SingleOrDefault(pe => e.ParentId = pe.Id);
}
但是肯定有办法告诉NHibernate为我做这个吗?
更新
目前我只尝试从数据库中获取所有内容,并希望NHibernate完成所有参考设置。但它没有:(
var getRoot = Session.Query<RootObject>().ToList();
var getRoot_hasMany = Session.Query<RootObjectCollection>().ToList();
var getRoot_hasMany_ref = Session.Query<RootObjectCollectionReference>().ToList();
var getRoot_hasMany_hasMany = Session.Query<RootObjectCollectionCollection>().ToList();
域:
根对象为getRoot
。它们有一个集合属性'HasMany'。这些HasMany每个都有一个返回GetRoot的引用,以及对另一个实体(getRoot_hasMany_ref)的引用,以及它们自己的集合(getRoot_hasMany_hasMany)。如果这没有意义,我将创建一个ERD,但实际结构与问题并不真正相关(我认为)。
这导致执行4个查询。 (这很好)
但是,在访问getRoot.First().HasMany.First().Ref
或getRoot.First().HasMany.First().HasMany().First()
等属性时,即使ISession
已经知道所有内容都已知,仍会导致额外的查询被执行?
那么我如何告诉NHibernate执行这4个查询,然后在不使用任何代理属性的情况下构建图形,...这样即使在ISession
超出范围之后我也可以访问所有内容?
答案 0 :(得分:1)
我认为其中有几个问题。
我停止尝试过多地欺骗NHibernate。我不会从多个线程访问实体,因为它们通常不是线程安全的。至少在使用延迟加载时。因此缓存懒惰的实体是邪恶的。
我会通过使用批量大小避免过多的查询,这是最干净,最简单的解决方案,在大多数情况下都足够好了#34;它对业务逻辑完全透明,这使它非常酷。
我会:
通常,查询时间作为刷新时间不太重要。 NH使用此时间来查找会话中更改的实体。为避免这种情况,请尽可能使实体只读。
答案 1 :(得分:1)
如果整个对象树永远不会改变(配置设置?),那么只需在初始化所有引用/集合的情况下高效加载它们
using(var Session = Sessionfactory = OpenSession())
{
var root = Session.Query<RootObject>().FetchMany(x => x.Collection).ToFutureValue();
Session.Query<RootObjectCollection>().Fetch(x => x.Ref).FetchMany(x => x.Collection).ToFuture();
// Do something with root.Value
}