C# 如何映射集合<;T>;在尼伯内特?
我有一个类Contact(基类),一个类Customer和一个类Supplier。Customer和supplier类都源于Contact 客户与订单的关系为0..n。我想在customer上有一个Collection属性,并在NHibernate中将其映射到相应的表 在NHibernate(版本2.0.1 GA)中如何实现这一点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
(注:使用.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 多次出现在包中
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。