代码之家  ›  专栏  ›  技术社区  ›  Ryan H

事务提交时获取多个查询,为什么?

  •  3
  • Ryan H  · 技术社区  · 15 年前
    public Parent GetByName(string Name)
    {
        return _session.CreateCriteria<Parent>()
            .Add(Restrictions.Eq("Name", Name))
            .SetFetchMode("Children", FetchMode.Eager)
            .SetResultTransformer(new DistinctRootEntityResultTransformer())
            .UniqueResult<Parent>();
    }
    
    public ParentDetailVM GetMeAParent(string Name)
    {
        Parent parent;
        using (var tx = _session.BeginTransaction())
        {
            //This works well, one single query loading
            //both parent and children
            parent = _parentRepository.GetByName(Name);
    
            //If I include this as suggested by NHProfiler
            //it all of the sudden sends a new query for each child
            //and a query for the grandchildren collection
            tx.Commit();
        }
    
        return Mapper.Map<Parent, ParentDetailVM>(parent);
    }
    

    我已检查以确保映射文件中没有任何内容设置为“急切加载”。如果不执行事务提交,我不明白为什么它会工作,否则它会发出N个以上的查询。有人知道为什么会这样吗?

    1 回复  |  直到 15 年前
        1
  •  0
  •   Jamie Ide    15 年前

    如果你检查 _session.IsDirty() 在提交交易之前,我打赌它会返回true。当事务被提交时,会话被刷新,并且由于某种原因,子对象被加载以级联更改。

    这是一个称为“重影”或幻影更新的问题。典型的情况是,数据库列是可为null的int,但相应的对象属性是不可为null的。当检索到具有空值的记录时,NHibernate将属性值设置为0,因此对象是脏的。

    解决此问题的最快方法是使用启用对象的动态更新 dynamic-update="true" 在XML映射中, DynamicUpdate() 在fluent中,并使用探查器或日志来查看在选择之后哪些列正在更新。还有一个实用程序叫做 Ghostbuster 可以包含在单元测试中。

    推荐文章