【问题标题】:ORM (NHibernate), DDD and saving complex entitiesORM (NHibernate)、DDD 和保存复杂实体
【发布时间】:2012-11-19 02:19:18
【问题描述】:

我是 NHibernate 的新手(坦率地说是 DDD 概念),所以我的问题可能很简单或无关紧要,但如果有人帮助我解决我的困惑,我将非常感激。

在我的应用程序中,我使用 DDD 和 NHibernate 作为 ORM。

使用简单的实体它可以正常工作,但现在我处于我的实体变得非常复杂的阶段(所以实体 A 包含实体 B 和实体 C 的数组;每个实体 C 包含 D 和一些其他参数等等...)

我的客户端应用程序正在通过 Internet 与 WCF 服务(与 db 通信)通信,因此速度(有效负载大小很重要)。在少数情况下,我必须将这些复杂 DTO 的数组从服务发送到客户端,然后客户端更新 A 中的少量值并将其发送回服务器进行保存/更新。

为了减少有效负载,我试图在从服务向客户端发送数据时,通过在我的映射器(我没有使用自动映射器等)中取消它们来从我的 DTO 中的 B 和 C 实体中删除未使用的属性值。

现在,当谈到将实体保存回 db 时,我应该怎么做?如果我在 B 和 C 的几个变量中传回具有空值的实体 A(我已在映射器中手动取消),NHibernate 将在我保存 A 时尝试保存 B 和 C。我只想保存 A,并且要求 NHibernate 不要从 B 或 C 中保存任何内容。

任何帮助,都是对我的祝福。

提前致谢, D

【问题讨论】:

    标签: nhibernate domain-driven-design


    【解决方案1】:

    这种情况下的解决方案可以在预测中找到。简而言之:

    • 保持映射正确且复杂。
    • 但在选择数据时,只将需要的列放入select 子句。

    这可以通过Projections 完成。可以在这里找到很好的详细解释:

    http://shareyour-experience.blogspot.cz/2011/07/exploring-nhibernate-projections-and.html

    文档:

    http://nhibernate.info/doc/nh/en/index.html#querycriteria-projection

    当数据返回服务器时,您的完全映射实体将能够保留所有属性。

    【讨论】:

    • 非常感谢 Radim 的解释。
    【解决方案2】:

    一旦实体变得复杂,最好将调用实体行为的命令概念与实体本身的结构分离。 (在这种情况下,命令是指表示执行操作的请求的 DTO)。您可以使用如下所示的命令:

    class DoSomethingToAnEntityCommand
    {
      public string EntityId { get; set; }
      public int SomeValue { get; set; }
    }
    

    当应用服务处理此命令时,它会加载所需的实体并调用该实体上的适用行为并提交事务。

    下一步是将查询与命令分离。当您从数据库中检索要作为 DTO 返回的实体时,您不必使用与加载要操作的实体相同的检索机制。正如您所指出的,即使对于单个实体,查询要求也会有所不同。有些查询只需要实体的一部分,加载整个实体的成本可能太高。有多种方法可以仅加载实体的一部分。正如 Radim Köhler 所述,您可以使用 NHibernate 投影。另一种选择是在 NHibernate 之外直接使用 SQL 查询。使用任一选项,返回的对象都不会被持久化 - 它们仅用于满足查询要求。

    当您需要在实体上调用行为时,您不需要传递表示该实体的整个对象图。您只需要传递相应实体的 ID 以及执行代码示例中所示的给定操作所需的任何参数。这就是 NHibernate 的用武之地——它可以通过 ID 加载实体并跟踪在操作期间所做的任何更改以持久化回数据库。

    【讨论】:

    • 感谢列夫的解释。不幸的是,我无法将两个答案标记为已接受。再次感谢。
    猜你喜欢
    • 2021-10-31
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多