Как добавить элементы в двусторонние отношения «один ко многим» в NHibernate? - PullRequest
1 голос
/ 21 апреля 2011

Скажем, у меня есть следующие классы 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.Items и Item.ContainerBox независимо от того, является ли Box новым или сохранился из базы данных.

1 Ответ

3 голосов
/ 21 апреля 2011

Измените _Items на защищенный и установите свободное отображение в свойстве _Items, и это будет работать нормально.Я использовал эту технику несколькими способами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...