代码之家  ›  专栏  ›  技术社区  ›  Emidee

获取在其他会话中修改的实体时出现问题

  •  0
  • Emidee  · 技术社区  · 16 年前

    我的富客户机应用程序中有一个奇怪的问题。以下是一些背景:

    • 每个视图模型使用一个会话。
    • 我的视图模型通过 Mediator .

    我有一个管理视图模型,在其中显示我的实体列表。我可以编辑一个实体,这将导致打开一个新的视图模型,该模型接收要通过中介编辑的实体的ID。

    当用户单击“编辑”按钮时,我的编辑视图模型会使用自己的会话更新实体,并再次使用具有已编辑实体ID的中介器请求主视图模型刷新实体列表。

    假设我在实体上更改了一个名为visible的布尔属性。

    当我编辑实体时,我可以看到对nhibernate的更新调用,更新数据库中的实体。

    当我回到主视图模型时,我做了两件事:

    1. 我向NHibernate询问更新后的实体
    2. 我刷新实体列表,显示所有实体,并使用自定义过滤器。(例如,显示所有可见的实体。)

    奇怪的是,我在第一条指令中从nh获得的实体仍然具有可见属性的旧值,但是在我的可见实体列表中,我编辑的实体不存在…

    下面是我用于分别获取实体和获取所有可见实体列表的存储库的两个功能:

    public virtual TEntity Get(int id)
    {
        return Session.Get<TEntity>(id);
    }
    
    public IEnumerable<Player> GetAllPlayersSortedByLastName(bool visible = true)
    {
        return from player in Session.Linq<Player>()
                where player.Visible == visible
                orderby player.LastName
                select player;
    }
    

    我的代码怎么了?为什么我从主视图模型的nh返回的实体在编辑后没有正确的值?

    提前谢谢

    1 回复  |  直到 16 年前
        1
  •  3
  •   Goblin    16 年前

    在每个视图模型的生命周期中,您保持ISession的活动状态吗?

    如果是这样的话——这个实体存在于MainViewModel的ISession的IdentityMap中——所以当您要求它刷新时——它只会获取IdentityMap中的那个实体。

    您需要isession.evict(updatedentity),然后再次运行查询。

    这就是ISession中第一级缓存的全部思想(如果数据库以前被加载过,就不会命中它)。

    如果不希望出现这种行为,并且希望绕过第一级缓存(您可以从会话中打开子会话),或者在IStaTelessSession中运行。