5

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

我的 qudry 是一种通用方法,因为似乎有很多选择。我的 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)...

首先: 这是正确的方法吗 - 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

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

4

4 回答 4

10

通常,DTO 不包含行为(如保存、加载),也不包含关于它们如何持久化的知识 (ISession)。听起来您真正创建的是数据层。理想情况下,您的业务层也不应该知道 ISession。也就是说,您可以根据自己的需要缩短此分层,但如果您的 ORM 流经所有层,则以后可能很难更改为不同的 ORM。

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

于 2009-10-07T09:02:48.630 回答
9

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

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

resultSet = session.CreateCriteria(typeof(MyDataObject))
    .Add(query criteria, etc.)
    .SetResultTransformer(Transformers.AliasToBean<MyDTOObject>())
    .List<IMyDTOObject>()
于 2009-10-07T13:06:52.403 回答
3

DTO's are meant to be "data transfer objects". That is, dumb objects used for passing values or collections of values around in your system. They shouldn't be responsible for persisting themselves, or even map 1-1 to domain objects in your domain layer.

于 2009-10-07T13:10:49.730 回答
2

ISession 的打开/关闭非常便宜。保持它打开太久的问题是连接池不能重用连接,直到它超时或者什么不是。这可能是多用户应用程序中的问题。

在您的场景中,我可能会采用面向服务的方法来存储检索数据。这意味着 DTO 只能在服务边界内内部使用。如果您需要复制看起来相同的对象,我建议您查看为此特定目的创建的AutoMapper 。如果您只有 Windows 或仅 Web 项目,那么这不是问题。就是混的时候。您不能在 Windows 应用程序中以与在 Web 应用程序中相同的方式处理会话。

于 2009-10-07T12:42:55.237 回答