代码之家  ›  专栏  ›  技术社区  ›  Patrick Peters

如何在nhibernate中映射集合<t>

  •  4
  • Patrick Peters  · 技术社区  · 16 年前

    我有一个类联系人(基类),一个类称为客户,一个类称为供应商。客户和供应商类都源自联系人。

    客户与订单之间存在0..n关系。我想在customer上有一个collection属性,并让它在nhibernate中映射到相应的表。

    如何在NHibernate(2.0.1版GA)中完成此操作?

    (PS:使用.NET 3.5 SP1、VS2008 SP1)

    2 回复  |  直到 16 年前
        1
  •  4
  •   Frederik Gheysels    16 年前

    这样做:

    创建这样的类:

    public class Customer  : Contact
    {
       private ISet<Order> _orders = new HashedSet<Order>();
    
       public Collection<Order> Orders
       {
          return new List<Order>(_orders);
       }
    
       // NOrmally I would return a ReadOnlyCollection<T> instead of a Collection<T>
       // since I want to avoid that users add Orders directly to the collection.
       // If your relationship is bi-directional, then you have to set the other
       // end of the association as well, in order to hide this for the programmer
       // I always create add & remove methods (see below)
    
       public void AddOrder( Order o )
       {
          if( o != null && _orders.Contains(o) == false )
          {
             o.Customer = this;
             _orders.Add(o);
          }
       }
    }
    

    在映射中,可以指定:

    <set name="Orders" table="OrdersTable" access="field.camelcase-underscore" inverse="true">
       <key column="..." />
       <one-to-many class="Order" .. />
    </set>
    

    既然您使用继承,那么您应该明确地了解NHibernate中继承映射的不同可能性,并选择最适合您情况的策略: inheritance mapping

    关于集合包语义: -将集合映射为集合时,可以确保映射集合中的所有实体都是唯一的。也就是说,nhibernate将确保在重新构建实例时,集合不包含重复项。 -将集合映射为包时,从数据库加载对象时,集合可能会多次包含同一个实体。

    • 集合是一组不同的 作为一个整体考虑的对象。一 一组(字母)的有效例子 是:A、B、C、D。每封信 只发生一次。
    • 包是集合的泛化。一 包的成员可以有多个 一个成员,而每个成员 集合只有一个成员身份。有效的 例如A、A、A、B、C, C,D,…}。字母A和C 在包中出现多次。
        2
  •  1
  •   Stefan Steinegger    16 年前

    如果您不喜欢使用来自IESI集合的集合,则另一个解决方案

    public class Customer  : Contact
    {
       public ICollection<Order> Orders
       {
          get; private set;
    
       }
    }
    

    像这样的映射:

    <bag name="Orders" table="Customer_Orders" >
       <key column="Customer_FK" />
       <composite-element>
         <property name="OrderNumber" />
         <property name="OrderName" />
         <!-- ... -->
       </composite-element>
    </set>