2010-07-16 60 views
0

的单位和我谈论这个问题的映射,可以发现here :)刷新实体抛出NHibernate.UnresolvableObjectException

这里是上下文:

我有一个父视图 - 模型,它有助于管理一些实体,并有自己的会话。

从这个VM中,我打开另一个视图模型(也有它自己的会话),对实体做一些更改(添加和/或删除子项),当我验证更改时,我提交会话并发出警告第一视图模型刷新显示器:

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

这里是父虚拟机的故障的方法:

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

例外是在刷新线抛出:

NHibernate.UnresolvableObjectException

并且所述消息是:

具有给定标识符的行存在[Emidee.CommonEntities.PlayerInTeam#3

我可以打开和多次改变的实体,但是当我删除一个孩子时,似乎抛出异常,然后再添加一个,最后删除另一个。

在网络上读了一些东西之后,似乎是因为当我刷新实体并且因为我改变了HasMany关系(因为我已经删除了一个播放器),NH试图重新加载删除的行。我试图在我的映射中的HasMany添加一个NotFound.Ignore语句,我试图强制一个新的查询到数据库而不是一个负载,但我仍然得到这个异常。

有人知道我该如何解决这个问题吗?

在此先感谢

迈克

+0

为什么不将使用的会话传递给“子”viewmodel?我认为这将解决问题并防止重新获取集合。 – Jay 2010-07-16 18:56:22

+0

因为我尝试应用ayende在这里执行的操作:http://msdn.microsoft.com/en-us/magazine/ee819139.aspx – Mike 2010-07-16 19:45:01

回答

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 2012-05-07 13:58:23

+0

如果另一个对象修改了现在驱逐的对象,则不会发生任何事情(并且也不会更新)。当然,如果你明确地调用'session.Update(oldObject)',它可能会失败。解决方案是......不这样做:-)被驱逐的对象应被视为不存在。 – 2012-05-07 14:45:02

+0

所以我需要找到所有被驱逐的引用,并将其替换为新引用。谢谢。 – schoetbi 2012-05-08 04:17:52

0

嗯,我刚刚发现了这个问题。

要更新团队的球员列表,我需要在更新实体之前清除列表并添加新球员。

现在,我通过删除和添加仅由用户移动的玩家来更新列表,而现在我没有任何问题。

这很奇怪。我不知道什么是错误的,但至少现在起作用。