我已在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辩论。
答案 0 :(得分:1)
文档说:“NHibernate 效果最好如果这些类遵循一些简单的规则,......”它并没有说它不起作用(显然它确实有用)。
所以,实际上,讨论归结为OO问题。
答案 1 :(得分:0)
实际上这只适用于属性。方法不会保留,因此proxies
和lazy-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不需要代理来处理它们。因此,它们可以是非虚拟的。