2010-05-08 58 views
0

假设我有订单系统。 每个“订单”引用“客户”对象。 当我填写数据访问层中的订单列表时,客户对象应该从 带来Customer Web Service“WCF”。 所以,我没有对顾客财产的次序来映射类映射,获取Nhibernate实体并从Web服务完成它

 Id(o => o.OrderID).GeneratedBy.Identity(); 
     //References(o => o.Customer).Not.Nullable().Column("CustomerID"); 
     HasMany(o => o.Details).KeyColumn("OrderID").Cascade.AllDeleteOrphan(); 
     Map(c => c.CustomerID).Not.Nullable(); 

,并要求NHibernate的会议让我的订单列表。 并试图循环在列表中的每一个订单,以填补它的客户财产, doe的任何机构有一个好主意,这?

IList<Order> lst = Session.CreateCriteria<Order>().List<Order>(); 
foreach (Order order in lst) 
       order.Customer = serviceProxy.GetCustomerByID(order.CustomerID); 

回答

0

所以你说你打了你的WCF,订单列表50,50倍。不太好。

你应该这样做:

var customers = serviceProxy.GetCustomersForIDs(lst.Select(x => x.CustomerID).Distinct()); //one hit to WCF 

    foreach(var order in lst) 
     order.Customer = customers.Single(x => x.ID == order.CustomerID); 

这对于性能老虎钳。

修改属性的客户,因为这:

,你可以做,是看中了(和不那么服务表现为主,但完全一样的服务表现为你的样品)的另一件事

 private customer; 
     public virtual Customer 
     { 
      get 
      { 
       if(customer == null) 
        customer = serviceProxy.GetCustomerByID(this.CustomerID); 
       return customer; 
      } 
     } 

如果您订单应该有一个serviceProxy的引用。

+0

对不起, Dmonlord,感谢您的回复,第一个解决方案看起来不错, ,但另一个解决方案,建议该模型应该有一个服务代理,这违反了企业应用程序模式恕我直言:引用意味着模型应该是持久无知的。 我对吗? – 2010-05-31 17:21:53

+0

好吧,我也会选择第一个解决方案。我不喜欢像ActiveRecord模式那样的花哨的东西,当应用程序变得更加复杂时,它可能会在你的腿上拍摄你。我留在服务/存储库模式和简单(或多或少的属性)域模型。我不在乎是否有人说这不是一个真正的领域驱动设计。 – dmonlord 2010-06-01 17:36:05

0

如果你真的想透明地做到这一点,尝试实现一个自定义tuplizer(和相关的东西)。看看this article,它为Java Hibernate实现了一个远程懒惰加载器,但是由于它具有相同的总体设计(tuplizers,懒惰初始化器,代理工厂等),所以一般概念同样适用于NHibernate。