开发者

How do I add items to a bi-directional one-to-many relationship in NHibernate?

开发者 https://www.devze.com 2023-02-27 23:11 出处:网络
Say I have the following classes Box and Item. Where a box contains many Items, and an Item can only be in one Box. An Item also knows what Box it is in.

Say I have the following classes Box and Item. Where a box contains many Items, and an Item can only be in one Box. An Item also knows what Box it is in.

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;}
 }

The Fluent NHibernate mapping classes might look like this.

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 );
}

In general this works, but it's not as robust as I would like, as you need to know how associate things correctly. For example the Box.Items.Add() method will add items to the Box, but n开发者_开发技巧ot update their ContainerBox properties. Like wise setting the Item.ContainerBox property does not add the item to the box.

So I figured I'd make Box.Items and IEnumerable to get rid of the Add() method, and instead add my own AddItem() method that will also set the Item.ContainerBox property.

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);
   }
}

I'm new to NHibernate, but I'm pretty sure this is a bad idea. Because, when a Box is later persisted from the database Box.Items wont point at _Items but rather will be overridden to point at some other NHibernate specific proxy collection. So calling Box.AddItem() on the persisted box, I think, wont actually add a new Item to the Box.

What is the correct way to do this? I'd like to have a single way to add an Item to a Box which updates Box.Items and Item.ContainerBox regardless of whether the Box is new or persisted from the database.


Change _Items to protected and set your fluent mapping to the _Items property and this will work just fine. I've used this technique in a number of ways.

0

精彩评论

暂无评论...
验证码 换一张
取 消