C# 如何映射集合<;T>;在尼伯内特?

C# 如何映射集合<;T>;在尼伯内特?,c#,visual-studio-2008,nhibernate,C#,Visual Studio 2008,Nhibernate,我有一个类Contact(基类),一个类Customer和一个类Supplier。Customer和supplier类都源于Contact 客户与订单的关系为0..n。我想在customer上有一个Collection属性,并在NHibernate中将其映射到相应的表 在NHibernate(版本2.0.1 GA)中如何实现这一点 (注:使用.NET 3.5 SP1,VS2008 SP1)这是这样做的: public class Customer : Contact { private

我有一个类Contact(基类),一个类Customer和一个类Supplier。Customer和supplier类都源于Contact

客户与订单的关系为0..n。我想在customer上有一个Collection属性,并在NHibernate中将其映射到相应的表

在NHibernate(版本2.0.1 GA)中如何实现这一点


(注:使用.NET 3.5 SP1,VS2008 SP1)

这是这样做的:

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);
      }
   }
}
<bag name="Orders" table="Customer_Orders" >
   <key column="Customer_FK" />
   <composite-element>
     <property name="OrderNumber" />
     <property name="OrderName" />
     <!-- ... -->
   </composite-element>
</set>
按如下方式创建您的类:

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);
      }
   }
}
<bag name="Orders" table="Customer_Orders" >
   <key column="Customer_FK" />
   <composite-element>
     <property name="OrderNumber" />
     <property name="OrderName" />
     <!-- ... -->
   </composite-element>
</set>
公共类客户:联系
{
私有ISet_orders=new HashedSet();
公共征收令
{
返回新列表(_订单);
}
//通常我会返回ReadOnlyCollection而不是Collection
//因为我想避免用户直接向集合添加订单。
//如果你的关系是双向的,那么你必须设置另一个
//关联的结尾,以便为程序员隐藏这一点
//我总是创建添加和删除方法(见下文)
公共命令(命令o)
{
如果(o!=null&&&u orders.Contains(o)==false)
{
o、 顾客=这个;
_命令。加入(o);
}
}
}
在映射中,可以指定以下内容:

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

由于您使用了继承,因此您应该明确了解NHibernate中关于继承映射的不同可能性,并选择最适合您的情况的策略:

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

  • 集合是一组不同的集合 作为一个整体考虑的对象。A. 一组(字母)的有效示例 是:{a,b,c,d}。每封信 只发生一次
  • 袋子是集合的概括。A. 一个包的成员可以有多个 一个成员,而每个成员 集合只有一个成员。有效的 袋子的例子是{a,a,a,b,c, c、 d,…}。字母a和c 多次出现在包中

如果您不喜欢使用Iesi集合中的集合,请选择另一种解决方案

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

   }
}
公共类客户:联系
{
公开收集令
{
获得;私人设置;
}
}
映射如下所示:

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);
      }
   }
}
<bag name="Orders" table="Customer_Orders" >
   <key column="Customer_FK" />
   <composite-element>
     <property name="OrderNumber" />
     <property name="OrderName" />
     <!-- ... -->
   </composite-element>
</set>


你跑得更快了。。。这里还有继承描述-我在示例中使用集合。。。仍然可能吗?仍然可能,但在我的示例中,private _orders成员必须是ISet类型,因为它映射为一个集合。例如,如果你想让订单成为一个列表,你就必须把它映射成一个包。(但是包映射有其他语义,然后是集合映射)。如果将public Orders属性的返回类型更改为collection,则这不是问题(在本例中),因为NHibernate不使用public属性,但私有字段是(因此映射中的access属性)@Frederik:您是否可以编辑您的答案以使其与collection一起工作,包括正确的映射文件。你能再描述一下包映射和集合映射之间的语义差异吗?@Frederik:如果集合中有一对多映射,那么table属性不会起任何作用。要么使用表和复合元素,要么使用对实体的引用,该实体通过一对多映射到其他地方。顺便说一句,我不会写一个属性在每次调用它时都创建一个新列表。更好的是:你的集合是否有序?我的意思是:在存储和从数据库取回元素之后,您希望元素的顺序相同吗?集合必须以我向其中添加项的方式存储。因此,添加orderA、orderB、orderC并再次读取,它必须按此顺序保存orderA、orderB和orderC。