2

我们使用 Fluent NHibernate 1.3.0.727 和 NHibernate 3.3.0.4000 将我们的属性映射到数据库中的列。这是我们的一个 ClassMap 的缩写示例:

    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();

但是,这似乎对该属性是否实际被代理没有任何影响。

有没有什么办法可以避免/减少这种代理开销?

4

3 回答 3

1

是的!.Not.LazyLoad()为了救援!

    public TankMap()
    {
        Id(o => o.Id);
        Map(o => o.TankSystem).Not.LazyLoad();
    }

我找到了一个很好的简短解释:

您可能想知道 Not.LazyLoad() 是什么意思。默认情况下,Fluent NHibernate 定义了使用延迟加载的映射。但这也意味着我们实体的所有属性都必须是虚拟的(代理)。

资源

于 2012-05-02T17:53:03.537 回答
1

我真的会小心在您的映射中使用 .Not.LazyLoad() 并根据需要在您的查询中急切加载。如果延迟加载获取策略配置不正确,问题可能会出现。始终最好使用 NProf 之类的工具检查每个查询。

林克:

var tanks = _session.Linq<Tank>()
               .Fetch(x=>x.TankSystem)
               .ToList();

QueryOver(我的首选): var tank = _session.QueryOver() .Fetch(x=>x.TankSystem).Eager .List();

TankSystem tankSystemAlias = null;
var tanks = _session.QueryOver<Tank>()
                .JoinAlias(x=>x.TankSystem, () => tankSystemAlias, JoinType.InnerJoin) // or JoinType.LeftOuterJoin
                .List()
于 2012-05-03T07:10:31.297 回答
0

避免在对象上具有虚拟属性的一种方法是:

public TankMap()
{
        Id(o => o.Id);
        this.Not.LazyLoad(); 
        Map(o => o.TankSystem);
}

这样就没有属性代理魔法。

于 2012-05-02T17:54:33.233 回答