2010-07-16 3 views
0

ПРИМИТИВЫ и отображений я говорю о в этом вопросе можно найти here :)Освежающий объект выбрасывает NHibernate.UnresolvableObjectException

Вот контекст:

У меня есть родительский Вид- которая помогает управлять некоторыми объектами и имеет свою собственную сессию.

От этой виртуальной машины я открываю другую модель представления (со своим собственным сеансом), выполняю некоторые изменения для объекта (добавляет и/или удаляет дочерние элементы), и когда я проверяю изменения, я фиксирую сеанс и предупреждаю первый вид-модель для обновления дисплея:

public void Validate() 
{ 
    using (var tx = Session.BeginTransaction()) 
    { 
     try 
     { 
      SelectedTeam.ClearRoster(); 

      foreach (var teamPlayer in TeamPlayers) 
       SelectedTeam.AddPlayer(teamPlayer); 

      teamsRepository.SaveOrUpdate(SelectedTeam); 

      tx.Commit(); 
     } 
     catch (Exception ex) 
     { 
      tx.Rollback(); 
     } 
     finally 
     { 
      if (tx.WasCommitted) 
       ServiceLocator.Current.GetInstance<Mediator>().NotifyColleagues(MediatorMessages.DisplayEntityInfos, SelectedTeam.Id); 
     } 
    } 
} 

Вот нарушенный метод родительского VM:

public void RefreshEntitiesListAndDisplayEntityInfos(int selectedEntityId) 
{ 
    TEntity entity = entitiesRepository.Load(selectedEntityId); 
    Session.Refresh(entity); 
    //... 
} 

исключения брошено на Refresh линии:

NHibernate.UnresolvableObjectException

И сообщение:

Нет строки с данным идентификатором существует [Emidee.CommonEntities.PlayerInTeam # 3

Я могу открыть и изменить юридическое лицо несколько раз, но кажется, что исключение выбрасывается, когда я удаляю дочерние элементы, а затем добавляю еще один и, наконец, удаляю другой.

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

Я попытался добавить оператор NotFound.Ignore в HasMany в мои сопоставления, я попытался принудительно ввести новый запрос в БД вместо загрузки, но я все еще получаю это исключение.

Кто-нибудь знает, как я могу это исправить?

Заранее спасибо

Майк

+0

Почему бы не пройти сеанс, используемый для «детской» модели просмотра? Я думаю, что это решит проблему и предотвратит повторную выборку коллекции. – Jay

+0

Поскольку я пытаюсь применить то, что ayende рекомендует делать здесь: http://msdn.microsoft.com/en-us/magazine/ee819139.aspx – Mike

ответ

4

Это известное поведение при обновлении объектов с измененными коллекциями.

Чтобы принудительно перезагрузить, измените свой метод на выполнение session.Evict с объектом как параметром. Это код, который мы используем в нашем базовом классе модели:

public T ReGet<T>(T entity) where T : IEntity 
{ 
    var id = entity.Id; 
    Session.Evict(entity); 
    return Session.Get<T>(id); 
} 
+0

Что произойдет, если другие объекты содержат ссылку на старый (теперь выдвоенный) объект и делает изменения на этом. Затем я получаю исключение NonUniqueObjectException, говорящее, что у меня есть два объекта для одного и того же ID. Знаете ли вы, что делать в таком случае? Благодарю. – schoetbi

+0

Если другой объект изменяет теперь выдворенный объект, ничего не произойдет (и ничего не будет обновлено). Конечно, если вы вызовете 'session.Update (oldObject)' явно, это, скорее всего, не удастся. Решение ... не делает этого :-) выведенный объект должен считаться несуществующим. –

+0

Так что мне нужно найти все ссылки на выселённый и заменить его новым. Благодарю. – schoetbi

0

Ну, я только что заметил проблему.

Чтобы обновить список игроков в группе, я использовал для очистки списка и добавления новых игроков перед обновлением объекта.

Теперь я обновляю список, удаляя и добавляя только игроков, которые были перемещены пользователем, и теперь у меня нет никаких проблем.

Это странно. Я не знаю, что было раньше, но как минимум работает сейчас.

Смежные вопросы