2010-12-10 4 views
6

я есть х которых объект типа ObjectX, который имеет свойство ListOfObjectYs тотВ NHibernate, не в состоянии обновить список дочерних объектов

List<objectY> 

NHibernate отображение выглядит следующим образом:

public ObjectXMap() 
    { 
     HasMany(x => x.ListOfObjectYs).AsBag().Inverse(); 
    } 

, когда я иду, чтобы сохранить его, я изменить некоторые свойства на ObjectX и затем :

Session.SaveOrUpdate(x); 

Теперь мне нужно обновить это свойство, которое является списком. Я получаю новый список objectYs, и я хочу заменить существующий список объектовY новым списком. мне нужно это сделать?

foreach (ObjectY y in x.ListOfObjectYs) 
       { 
        Session.Delete(y); 
        deleted = true; 
       } 
       if (deleted) 
       { 
        _session.Flush(); 
       } 
       x.ListOfObjectYs.Clear(); 

       foreach (ObjectY y in newObjectYList) 
       { 
        x.ListOfObjectYs.Add(y); 
        Session.SaveOrUpdate(y); 
       } 
       _session.Flush(); 

мои вопросы:

  1. Должен ли я удалить все и перенесут, прежде чем добавлять новые.
  2. мне нужно сделать все эти инкрементный сохраняет между

есть лучший способ сделать это обновление, где мне нужно обновить объект (свойства), но и обновить свойства, список которых есть ли весь новый список (это означает, что элементы необходимо удалить и добавить).

ответ

3

Ответы на ваши вопросы - нет, и нет. Если вы хотите заменить список, вы должны очистить его и добавить новые элементы. Если у вас есть каскад, установленный для all-delete-orphan, как и в ответе Джеймса Ковача, изменения в коллекции будут сохраняться, когда сеанс будет очищен.

Это важно понимать, что сохранение, обновление и SaveOrUpdate означают в NHibernate:

  • Сохранить - создать новый объект упорной
  • Update - сделать измененный отдельно стоящий объект упорного
  • SaveOrUpdate - Сохранить или Обновление в зависимости от несохраненной ценности идентификатора объекта

См. Также Manipulating Persistent Data.

Предполагая, что были загружены все ваши объекты в том же сеансе затем заменить коллекцию может быть столь же легко, как:

x.ListOfObjectYs.Clear(); 
foreach (ObjectY y in newObjectYList) 
{ 
    x.ListOfObjectYs.Add(y); 
} 
_session.Flush(); 
3

Вам нужен каскад на вашем HasMany(). Если дочерние объекты полностью принадлежат родительскому элементу, Cascade.AllDeleteOrphan() является хорошим выбором. Таким образом, сохранение, обновление и удаление родительского элемента автоматически каскадируются на дочерние объекты, что устраняет необходимость в вашем сложном блоке foreach. При этом просто обновите свою коллекцию и совершите транзакцию. NHibernate позаботится обо всем остальном.

UPDATE: Чтобы изменить список, просто добавьте и удалите элементы из списка, как обычно, с помощью коллекции .NET. Например:

public void RemoveY(ObjectY someY) { 
    ListOfObjectYs.Remove(someY); 
} 

public void AddY(ObjectY someY) { 
    ListOfObjectYs.Add(someY); 
} 

public void ClearAllY() { 
    ListOfObjectYs.Clear(); 
} 

Когда сделка совершается, любые изменения в коллекции ListOfObjectYs будут сохранены вместе с родителем ObjectX.

+0

быть ясно, я добавить Cascade.AllDeleteOrphan() в мой файл отображения. Этого достаточно. Можете ли вы предоставить синтаксис для обновления списка, поскольку я не совсем понимаю, что вы имеете в виду, «я могу просто удалить их для каждого», в какой-то момент мне нужно удалить существующие записи и добавить новые. Я не вижу, как я выхожу из этого. – leora 2010-12-10 03:25:50

+0

- теперь я получаю сообщение об ошибке: сбор с cascade = "all-delete-orphan" больше не ссылался на экземпляр объекта-владельца: ObjectY – leora 2010-12-10 03:52:04