更改集合后的Nhibernate查询

时间:2014-07-07 05:05:23

标签: nhibernate queryover

User有很多Role s:

public class User
{
    private ISet<Role> _roles = new HashSet<Role>();
    public virtual ISet<Role> Roles { get { return _roles; } }
}

我向用户添加角色(user1.Roles.Add(role1))。

为什么这两个查询中的第一个不会将user1作为第二个返回?

session.QueryOver<User>()
    .JoinQueryOver<Role>(u => u.Roles)
    .Where(x => x.Id == role1.Id)
    .List();    

session.QueryOver<User>().List()
    .Where(u => u.Roles.Contains(role1));

1 个答案:

答案 0 :(得分:0)

魔法行为的答案隐藏在Session模式及其.Flush()操作中。

ISession(见Chapter 2. Architecture):

  

ISession(NHibernate.ISession)

     

单线程,短期对象,表示应用程序与持久性存储之间的对话。包装ADO.NET连接。 ITransaction的工厂。 保存持久对象的强制(第一级)缓存,在导航对象图或按标识符查找对象时使用。

这里有趣的是first-level缓存... identifier。发生的事情是User内部更新了ISession。仅在此会话中,因为它未与DB同步...它没有刷新

9.6. Flush(简而言之) NHibernate的方式

  

ISession会不时执行同步 ADO.NET连接状态所需的SQL语句内存中保存的对象状态。此过程刷新默认情况下发生在以下几点......(请参阅链接中的更多内容)

所以,我们现在知道的是:会话正在保持用户的更新记录。 DB没有,因为没有调用session.Flush()。我们运行第二个查询,如下所示:

session.QueryOver<User>()
// forces to load all rows from DB
// these rows are converted into User instances by their ID
// and while our updated User in memory already is... it will be used
// instead of persisted one
.List()
// now we do in memory searching
// i.e. check the User instances, which of them does have role1
// and even our newly updated (just in memory) user is found
.Where(u => u.Roles.Contains(role1));

第二个查询,确实在数据库端进行过滤...但未完成同步...没有.Flush() ...找不到用户。

所以,请阅读上面提到的内容,以便更详细地了解:会话,一级缓存和刷新

打电话:

session.Flush() // after adding Role1 to User

在向用户添加角色时立即...并且两个查询都将返回相同的结果