说我有以下类Box和Item。框中包含许多项目,而项目只能在一个框中。物品也知道它在哪个盒子里。
public class Box
{
public virtual int BoxID {get; set:}
public virtual string Name {get; set;}
public virtual IList<Item> Items {get; set;}
}
public class Item
{
public virtual int ItemID {get; set;}
public virtual string Name {get; set;}
public virtual Box ContainerBox {get; set;}
}
Fluent NHibernate映射类可能如下所示。
public class BoxMap:ClassMap<Box>
{
Id(b=>b.BoxId);
Map(b=>b.Name);
HasMany(b => b.Items)
.Inverse()
.CascadeAll();
}
public class ItemMap:ClassMap<Item>
{
Id(i=>i.ItemId);
Map(i=>i.Name);
References(i => i.ContainerBox );
}
一般情况下这是有效的,但它并不像我想的那样强大,因为你需要知道如何正确地关联事物。例如,Box.Items.Add()
方法会向Box添加项目,但不会更新其ContainerBox
属性。与明智的设置一样,Item.ContainerBox
属性不会将项目添加到框中。
所以我想我会使Box.Items和IEnumerable摆脱Add()方法,而是添加我自己的AddItem()方法,它也将设置Item.ContainerBox属性。
public class Box
{
private List<Item> _Items = new List<Item>();
public virtual int BoxID {get; set:}
public virtual string Name {get; set;}
public virtual IEnumerable<Item> Items
{
get{return _Items;}
private set
{
_Items.Clear();
_Items.AddRange(value);
}
}
public void AddItem(Item i)
{
if(i.ContainerBox != null) throw new Exception("Item is already in a box!");
i.ContainerBox = this;
_Items.Add(i);
}
}
我是NHibernate的新手,但我很确定这是一个坏主意。因为,当一个Box稍后从数据库Box.Items
持久化时不会指向_Items
,而是会被覆盖以指向其他一些NHibernate特定的代理集合。因此,我认为,在持久框中调用Box.AddItem()
实际上不会在框中添加新项目。
这样做的正确方法是什么?我想有一种方法可以将一个Item添加到Box中,无论Box是新的还是从数据库中持久化,它都会更新Box.Items和Item.ContainerBox。
答案 0 :(得分:3)
将_Items
更改为protected并将您的流畅映射设置为_Items
属性,这样就可以了。我在很多方面都使用过这种技术。