在(Fluent)NHibernate实体/用作业务对象层中实现保存方法?坏主意?

在(Fluent)NHibernate实体/用作业务对象层中实现保存方法?坏主意?,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,在使用Fluent NHibernate时,我尝试在实体对象中实现一个save方法。这是一个不折不扣的可怕想法吗?似乎这将是我的演示文稿和数据库之间的完美接口,但事实上,我需要在所有内容上设置虚拟关键字,这让我觉得这从来没有打算像这样使用 实体: 基类: 我认为这是个坏主意。现在看起来很方便,但如果你的域名发展到中等规模,它可能会变得相当混乱 使用NHibernate可能不会有那么糟糕的结果,但我们有一个域模型,使用了类似的方法,它最终与我们的ORM耦合得太多。这使得我们第一次试图离开我们古老而

在使用Fluent NHibernate时,我尝试在实体对象中实现一个save方法。这是一个不折不扣的可怕想法吗?似乎这将是我的演示文稿和数据库之间的完美接口,但事实上,我需要在所有内容上设置虚拟关键字,这让我觉得这从来没有打算像这样使用

实体:

基类:


我认为这是个坏主意。现在看起来很方便,但如果你的域名发展到中等规模,它可能会变得相当混乱

使用NHibernate可能不会有那么糟糕的结果,但我们有一个域模型,使用了类似的方法,它最终与我们的ORM耦合得太多。这使得我们第一次试图离开我们古老而可怕的怪物时非常困难。如果你不小心的话,它也会让测试变得有趣。这与我们必须生成自己的延迟加载代码这一事实有很大关系,因此您的里程数可能会有所不同,但我认为这确实污染了您的域层。实现存储库或可查询模式不需要花费太多的精力,它将使您的域模型更干净


旁白:您不希望每次都创建一个会话工厂—您希望在应用程序生命周期中创建一次,然后在每次需要时创建一个会话,或者可能不太频繁—请考虑一下,如果你对会话和会话工厂感到困惑,我不久前在回答一个类似的问题时写道

我同意@AlexCuse


上述实现中还缺少的另一件事是,您不能在同一事务中保存多个业务对象或不同类型的业务对象,这通常是必需的。

如前所述,这是一个非常糟糕的主意

但实际上,你要做的是一个众所周知的模式:

我链接到的项目是基于NHibernate的,它已经有了一个带有Save和其他实现方法的基类

public class MyTable : BusinessObject
{
    #region Properties
    /* ... */
    #endregion

    public virtual void Save()
    {
        var sf = CreateSessionFactory();
        using (var s = sf.OpenSession())
        {
            using (var t = s.BeginTransaction())
            {
                s.SaveOrUpdate(this);
                t.Commit();
            }
        }
    }
}
public abstract class BusinessObject
{
    protected static NHibernate.ISessionFactory CreateSessionFactory()
    {
        return FluentNHibernate.Cfg.Fluently.Configure()
            .Database(...)
            .Mappings(...)
            .BuildSessionFactory();
    }

}