我们正在使用Fluent NHibernate 1.3.0.727和NHibernate 3.3.0.4000将我们的属性映射到数据库中的列。以下是我们的ClassMaps之一的缩写示例:
public class TankMap : ClassMap<Tank>
{
public TankMap()
{
Id(o => o.Id);
Map(o => o.TankSystem);
}
}
在这种情况下,TankSystem属性是字符串。
在我们的应用程序的一些部分中,有许多计算涉及多次访问映射的属性(例如TankSystem)。当我们分析应用程序时,简单地访问这些属性会花费相当多的时间,因为每次访问它们时,都必须通过NHibernate.Proxy.DefaultLazyInitializer.Intercept方法。
我们需要尽可能快地进行计算,并希望避免这种代理开销。一种方法是将我们想要的属性(例如TankSystem)复制到数组中,并在我们想要访问此信息的任何时候使用数组,但这不是一种非常面向对象的方法。
更新
我们尝试使用Not.LazyLoad映射我们的属性,例如:
Map(o => o.TankSystem).Not.LazyLoad();
但是,这似乎对此属性是否实际代理没有任何影响。
是否有任何类型的选项可以避免/减少这种代理开销?
答案 0 :(得分:1)
是的! .Not.LazyLoad()
救援!
public TankMap()
{
Id(o => o.Id);
Map(o => o.TankSystem).Not.LazyLoad();
}
我找到了一个简短的解释:
您可能想知道Not.LazyLoad()的含义。默认情况下,Fluent NHibernate定义使用延迟加载的映射。但这也意味着我们实体的所有属性都必须是虚拟的(代理)。
答案 1 :(得分:1)
我会非常小心在您的映射中使用.Not.LazyLoad(),并根据需要在您的查询中加载。如果未正确配置lazyload fetch策略,问题可能会增加。最好使用像NHProf这样的工具检查每个查询。
的LINQ:
var tanks = _session.Linq<Tank>()
.Fetch(x=>x.TankSystem)
.ToList();
QueryOver(我的首选): var tanks = _session.QueryOver() .Fetch(X =&GT; x.TankSystem).Eager .LIST();
TankSystem tankSystemAlias = null;
var tanks = _session.QueryOver<Tank>()
.JoinAlias(x=>x.TankSystem, () => tankSystemAlias, JoinType.InnerJoin) // or JoinType.LeftOuterJoin
.List()
答案 2 :(得分:0)
避免在对象上使用虚拟属性的一种方法是:
public TankMap()
{
Id(o => o.Id);
this.Not.LazyLoad();
Map(o => o.TankSystem);
}
这种方式没有属性代理魔法。