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

Nhibernate 为什么这个静态方法在这个域类中是合法的?,nhibernate,Nhibernate,我在NHibernate文档中读到,所有持久类公共方法、属性和事件都必须声明为virtual 但是,尽管为未标记为虚拟的任何属性生成运行时错误,我发现允许使用静态方法,并且不会生成运行时错误。由于它们是静态的,所以它们当然没有标记为虚拟的,这似乎违反了文档第4.1.4点中的规则(见上文)。我已经检查了结果sql,当我对该方法运行测试时,它也正确地实现了延迟加载,因此使用静态方法可以吗 以下是persistant类的基本细节: public class CmsPage { public v

我在NHibernate文档中读到,所有持久类公共方法、属性和事件都必须声明为virtual

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

以下是persistant类的基本细节:

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;
    }
}
公共类CmsPage
{
公共虚拟int?Id{get;set;}
公共虚拟字符串标题{get;set;}
公共虚拟空间更新()
{
使用(ISession session=NHibernateHelper.OpenSession())
{
使用(ITransaction transaction=session.BeginTransaction())
{
更新(本);
Commit();
}
}
}
//注意:静态和非虚拟,但不会对Nhibernate造成问题
公共静态IEnumerable GetList()
{
IList页面列表;
使用(ISession session=NHibernateHelper.OpenSession())
{
字符串hql=“from CmsPage p”;
pageList=session.CreateQuery(hql)
.List();
}
返回页面列表;
}
}
所以我的问题是,为什么在持久域类中使用静态方法是可以的,而文档似乎说它不是


请从NHibernate的角度回答,而不是从OO设计的角度;如果可以避免的话,我不想卷入OOD/OOP的争论。

实际上,这只适用于属性。方法不会持久化,因此
代理
延迟加载
不适用。理想情况下,您应该将数据访问(本例中的静态方法)与域对象分开。但是你指出这一点是正确的,也许文档应该更清晰


总之,您的类非常好,但是如果您将关注点分开,它可能会更好。

实际上,这只适用于属性。方法不会持久化,因此
代理
延迟加载
不适用。理想情况下,您应该将数据访问(本例中的静态方法)与域对象分开。但是你指出这一点是正确的,也许文档应该更清晰

总之,您的类非常好,但是如果您将关注点分开,它可能会更好。

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

因此,实际上,讨论归结为一个OO问题。

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


因此,实际上,讨论归结为一个OO问题。

NHibernate需要所有属性都是虚拟的,因为它通过创建覆盖所有内容的对象代理来实现其延迟加载魔法。因此,当您编写此代码时:

class Foo {
    public virtual Foo[] Neighbors { get; set; }
}
NHibernate秘密生成如下类:

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

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

NHibernate需要您的所有属性都是虚拟的,因为它通过创建覆盖所有内容的对象代理来实现其惰性加载魔法。因此,当您编写此代码时:

class Foo {
    public virtual Foo[] Neighbors { get; set; }
}
NHibernate秘密生成如下类:

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

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

hmmm不知道它是否只是属性,而不管文档如何。谢谢我将它们保存在域对象中,因为我认为它不是真正的数据访问。传统上,我会一直有一个BLL DAL等,但它的NHibernate是做真正的数据访问。虽然HQL在域层可能不那么受欢迎,但我承认。。。我脑子里还没想清楚。我曾在存储库类中玩弄过这一切,但它给我留下了一个贫乏的域模型。我想我最终可能会在域中找到存根,这些存根最终会调用repo类中的东西。hmmm确实想知道,不管文档如何,它是否只是属性。谢谢我将它们保存在域对象中,因为我认为它不是真正的数据访问。传统上,我会一直有一个BLL DAL等,但它的NHibernate是做真正的数据访问。虽然HQL在域层可能不那么受欢迎,但我承认。。。我脑子里还没想清楚。我曾在存储库类中玩弄过这一切,但它给我留下了一个贫乏的域模型。我想我最终可能会在域中找到存根,这些存根最终会调用repo类中的东西。