【问题标题】:Best approach for building NHibernate DTO's构建 NHibernate DTO 的最佳方法
【发布时间】:2009-10-07 08:48:08
【问题描述】:

我是 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,以上都不是 :)

【问题讨论】:

  • 当一个对象知道如何保存自己称为DAO,这与DTO无关

标签: nhibernate hibernate fluent-nhibernate dto


【解决方案1】:

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

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

【讨论】:

  • 架构必须同时支持 web (Silverlight) 和 windows (WPF)
【解决方案2】:

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

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

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

【讨论】:

  • 我可以在 Add 方法中使用哪些条件(将域属性链接到 DTO 属性)?
  • @SilvioDelgado:很抱歉,我已经 3 年多没有使用 NHibernate 了,所以我不知道。
  • 没问题。还是非常感谢。 :)
【解决方案3】:

DTO 是“数据传输对象”。也就是说,用于在系统中传递值或值集合的哑对象。他们不应该负责持久化自己,甚至不应该将 1-1 映射到您的域层中的域对象。

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      • 2021-12-01
      • 1970-01-01
      • 2013-06-11
      相关资源
      最近更新 更多