会话关闭后加载子对象

load child objects after session closed

我想在会话关闭后加载一个子对象,无论如何都要这样做?

using (var session = NHibernateHelper<T>.OpenSession())
{
    Foo = session.CreateCriteria(Foo).List<Foo>();
}

using (var session = NHibernateHelper<T>.OpenSession())
{
     Foo.Children.Load();
}


public static void Load<T>(this IList<T> list)
{
     //load foo with Children
}

我们可以在这里受益于 NHibernate 对处理分离对象的本机支持

19.1.4. Initializing collections and proxies

...
You may also attach a previously loaded object to a new ISession with Merge() or Lock() before accessing uninitialized collections (or other proxies). No, NHibernate does not, and certainly should not do this automatically, since it would introduce ad hoc transaction semantics!
...

调整后的 Load() 方法如下所示:

public static TEntity LoadCollection<TEntity, TItem>(
        this TEntity entity, 
        Func<TEntity, IList<TItem>> listGetter)
    where TEntity : class
{
    using (var session = NHibernateHelper<T>.OpenSession())
    {
        // here we get brand new - connected - instance of TEntity
        TEntity reAttached = session.Merge<TEntity>(entity);

        NHibernate.NHibernateUtil
            .Initialize(listGetter.Invoke(reAttached));

        return reAttached;
    }
}

调用方:

using (var session = NHibernateHelper<T>.OpenSession())
{
    IList<Foo> foos = session.CreateCriteria<Foo>()
            ...
            .List<Contact>();
}

Foo foo = foos.First();

// here we get merged instance with initiated
foo =  foo.LoadCollection(f => f.SomeCollection);

注意:这真的取决于我们为什么需要它。合并将需要更改引用(旧的分离对象将丢失)。
有时可以(甚至更好)通过会话直接将集合加载为 IList<TItem>,使用 Where ParentId = current.ID...只是一个想法...