如何确保对象延迟加载(Fluent)NHibernate?

时间:2010-09-22 12:57:30

标签: .net database nhibernate fluent-nhibernate lazy-loading

我在服务器端使用Fluent NHibernate来配置数据库。 Fluent默认使用Lazyloading,但是我明确地禁用了它,因为这在将对象发送到客户端时给了我一些问题。显然客户端无法懒惰加载对象,因为它无权访问数据库。

现在我尝试为我的数据模型的某些部分重新启用Lazyloading,因为有些部分我只想将toplevel对象返回给客户端。但是,它们似乎不是Lazyloaded。为什么?!

我禁用LazyLoading的做法是在映射对象和映射中的引用上添加Not.LazyLoading()。现在删除它似乎没有效果。调试我看到所有引用的对象,我也在客户端获取它们。但是,NHibernateUtil.IsInitialized(myObjectFromDb.SomeReference)同时正确地表示错误。所以;我如何确保对象是延迟加载的;得到一个对象缺少其引用回到客户端?我有什么想法可能会出错?

我有一些课程(非常简化的例子......):

public class Customer
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Order> Orders { get; set; }
}

public class Order
{
    public virtual int Id { get; set; }
    public virtual IList<Item> Items { get; set; }
}

public class Item
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}

简单映射 - 使用默认的LazyLoading:

public class CustomerMapping : ClassMap<Customer>
{
    public CustomerMapping()
    {
        Id(c => c.Id);
        Map(c => c.Name);
        HasMany(c => c.Orders);
    }
}

public class OrderMapping : ClassMap<Order>
{
    public OrderMapping()
    {
        Id(c => c.Id);
        HasMany(c => c.Items);
    }
}

public class ItemMapping : ClassMap<Item>
{
    public ItemMapping()
    {
        Id(c => c.Id);
        Map(c => c.Name);
    }
}

我直接用Session.Load<Customer>(id)获取它 - 直接在我的REST服务上返回结果,而不访问对象,以便加载延迟引用。在加载之后和返回到服务器端的对象上都加载了引用。我怎么能阻止这个?

1 个答案:

答案 0 :(得分:3)

做了一些更多的研究和测试。延迟加载结果与预期一样简单。这是映射中的默认行为,因此不说任何关于它的内容实际上会导致对象被延迟加载。

问题是:他们什么时候装?好吧 - 如果他们是Lazy Loaded,他们将在任何人需要时加载 - 在会话范围内。所以;在Debug-mode中检查对象以检查它是否被加载实际上会触发对象的加载 - 懒洋洋地。因此,检查员会将参考文献显示为已加载,并且一切都会正常。

我的案例中的问题是我提到的“在会话范围内”。我有一个客户端和服务器端。服务器提供REST服务,客户端使用HttpClient调用这些服务。在服务器上,数据将以XML格式包装,然后返回。在我的情况下,当我返回结果时,会话仍然存在 - 意味着数据的包装将在需要时懒惰地加载引用。所以我获得了所有引用,并将完整的对象返回给客户端。

因此;确保使用Fluent进行延迟加载NHibernate只是不要显式设置任何内容,然后要知道你是否真的以任何方式使用对象引用,因为这将导致它们被加载。