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.
精彩评论