构建NHibernate DTO的最佳方法

Ste*_*eve 5 nhibernate hibernate dto fluent-nhibernate

我是NHibernate(和ORMS)的新手,并试图掌握它所呈现的无数不同选项.作为参考,我使用Fluent NHibernate和单独的业务对象,而这些对象又使用DTO纯粹用于数据访问.我的应用程序架构必须同时支持Windows和Web"前端".

我的quandry是一种普遍的方法,因为似乎有很多选择.我的DTO看起来像下面的示例.每个DTO都引用了一个从BO传递给它们的ISession.他们负责自己的负载并保存:

public class EmployeeDTO...

    // Data Properties to be persisted to the database
    public virtual int Id { get; private set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual ISession Session { get; set; }

    // Save logic
    public virtual void Save()
    {
        var transaction = Session.BeginTransaction();
        Session.SaveOrUpdate(this);
        transaction.Commit();
    }

    // Load logic
    public virtual void Load(int id)...
Run Code Online (Sandbox Code Playgroud)

首先: 这是正确的方法吗 - DTO是否有能力自行保存和加载?

其次: 无论保存/加载代码在哪里,您是否应该在生命周期或对象中使用相同的ISession,还是应该在每次需要数据库交互时都对ISessionFactory和每个数据库交互都打开一个新会话?

    // Open a new session every time I interact with the repository
    var session = FluentSupport.SessionFactory.OpenSession();
    var transaction = Session.BeginTransaction();
    Session.SaveOrUpdate(this);
    transaction.Commit();
    session.Close();
    // Close the session when I'm done
Run Code Online (Sandbox Code Playgroud)

当然总有选项3,以上都不是:)

Mic*_*dox 10

通常,DTO不包含行为(如Save,Load),并且不包含它们如何被持久化的知识(ISession).听起来你真正创建的是一个数据层.理想情况下,您的业务层也不应该了解ISession.也就是说,您可以根据自己的需要快速切换所需的分层,但如果您的ORM渗透到所有图层,则可能很难在以后更改为其他ORM.

对于ISession生命周期管理,您必须决定是否要使用UnitOfWork模式,该模式基本上表示每个用户请求都会获得新的ISession.对于ISession的生命周期还有其他选择,你在这方面确实不受限制.通常,围绕Web应用程序与Windows应用程序相比,可能存在最佳实践,而不是其他任何应用程序类型,但您没有指定您正在编写的内容.


Jon*_*gel 9

将您的加载/保存代码与DTO分开.DTO对象仅是基础数据的视图.

在进行查询时,使用转换返回DTO.像这样的东西:

resultSet = session.CreateCriteria(typeof(MyDataObject))
    .Add(query criteria, etc.)
    .SetResultTransformer(Transformers.AliasToBean<MyDTOObject>())
    .List<IMyDTOObject>()
Run Code Online (Sandbox Code Playgroud)