NHibernate - 为什么这个静态方法在这个域类中是合法的?

时间:2009-11-17 15:36:28

标签: nhibernate

我已在NHibernate文档的Chapter 4中读到所有持久化类的公共方法,属性和事件必须声明为虚拟

但是,虽然为未标记为虚拟的任何属性生成了运行时错误,但我发现允许使用静态方法并且不会生成运行时错误。由于它们是静态的,因此它们当然没有标记为虚拟,这似乎违反了文档第4.1.4节中的规则(见上文)。我检查了生成的sql,当我对该方法运行测试时它也正确实现了延迟加载,因此可以使用静态方法吗?

以下是持久性课程的基本细节:

public class CmsPage
{
    public virtual int? Id { get; set; }
    public virtual string Title { get; set; }

    public virtual void Update()
    {
        using (ISession session = NHibernateHelper.OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                session.Update(this);
                transaction.Commit();
            }
        }
    }

    // Note: static and non-virtual and yet it will not cause a problem for Nhibernate
    public static IEnumerable<CmsPage> GetList()
    {
        IList<CmsPage> pageList;
        using (ISession session = NHibernateHelper.OpenSession())
        {
            string hql = "from CmsPage p";
            pageList = session.CreateQuery(hql)
                .List<CmsPage>();
        }

        return pageList;
    }
}

所以我的问题是,为什么在文档似乎说它不是在持久域类中使用静态方法呢?

请从NHibernate的观点回答不是OO的设计观点;如果可以避免,我不想参加OOD / OOP辩论。

3 个答案:

答案 0 :(得分:1)

文档说:“NHibernate 效果最好如果这些类遵循一些简单的规则,......”它并没有说它不起作用(显然它确实有用)。

所以,实际上,讨论归结为OO问题。

答案 1 :(得分:0)

实际上这只适用于属性。方法不会保留,因此proxieslazy-loading不适用。理想情况下,您应该将数据访问(在您的情况下为静态方法)与域对象分开。但是你指出这一点是正确的,也许文档应该更清楚。

总之,你的课程完全没问题,但如果你把问题分开,可能会更好。

答案 2 :(得分:0)

NHibernate需要所有属性都是虚拟的,因为它通过使对象的代理覆盖所有内容来执行其延迟加载魔法。所以当你写这段代码时:

class Foo {
    public virtual Foo[] Neighbors { get; set; }
}

NHibernate秘密生成类:

class NHProxy03450843275 : Foo {
    public virtual Foo[] Neighbors { /* Godawful lazy-loading magic goes here */ }
}

实际上它比这更糟糕,但这给了你一个想法。无论如何,静态方法没有绑定到类的特定实例,因此NH不需要代理来处理它们。因此,它们可以是非虚拟的。