如何在NHibernate中添加项目到双向一对多关系?

时间:2011-04-21 00:41:36

标签: nhibernate fluent-nhibernate

说我有以下类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。

1 个答案:

答案 0 :(得分:3)

_Items更改为protected并将您的流畅映射设置为_Items属性,这样就可以了。我在很多方面都使用过这种技术。