2012-11-19 33 views
1

我是新来的NHibernate(坦率地说,以DDD概念),所以我的问题可能是简单的或不相关的,但如果有人可以帮助我与我的困惑,我会非常感激。ORM(NHibernate的),DDD和保存复杂的实体

在我的应用我使用DDD和NHibernate作为ORM。

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

我的客户端应用程序是通过互联网交谈WCF服务(即谈话DB),因此速度(与有效载荷大小是相当重要的)。在少数情况下,我必须将这些复杂的DTO的数组从服务发送到客户端,然后客户端在A中更新少量值并将其发送回服务器进行保存/更新。

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

现在,当谈到拯救实体回分贝,我应该怎么办?如果我在B和C的几个变量(我已经在映射器中手动取消了该变量)将null值传回给实体A,那么当我保存A时,NHibernate将尝试保存B和C.我只想保存A,并且问NHibernate的不保存从B或C.

任何帮助什么,会祝福我。

由于提前, d在这种情况下

回答

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

当数据会回来在服务器上,你完全映射实体将能够坚持所有属性。

+0

非常感谢Radim的解释。 – Dharmesh

0

一旦实体变得复杂,最好是去耦是从调用实体本身的结构上的实体行为的命令的概念。 (在这种情况下的命令意味着代表执行操作的请求的DTO)。你可以有一个看起来像这样的命令:

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

当应用程序服务处理这个命令,它会加载所需的实体和该实体调用应用行为和提交事务。

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

当您需要在实体上调用行为时,不需要传递表示实体的整个对象图。您只需要传递相应实体的ID以及执行给定操作所需的任何参数(如代码示例中所示)。这就是NHibernate进来的地方 - 它可以通过ID加载实体,并跟踪操作过程中所做的任何更改,并将其保存回数据库。

+0

感谢列夫的解释。不幸的是,我不能将两个答案标记为已接受。再次感谢。 – Dharmesh