【问题标题】:nhibernate 'save' -> 'get' problemnhibernate 'save' -> 'get' 问题
【发布时间】:2009-08-17 08:45:11
【问题描述】:

你好,

我正在使用 nhibernate,但在我的网站上注册用户时遇到问题。

当用户想要注册时,我会在数据库中创建新的用户记录,然后系统会立即将用户登录。

这就是问题所在......创建用户记录时我正在使用

NHibernateSession.Save(实体); //不立即将用户对象保存到数据库中。它保留在会话中。

当我想登录用户时,我通过他的用户名加载用户,然后我得到空用户对象。

为什么我得到一个空对象,我怎样才能让它工作?

谢谢

【问题讨论】:

    标签: nhibernate load save


    【解决方案1】:

    好的,我刚刚测试了这个:

            ISession session = s.CreateSession();
    
            User user = new User();
    
            user.Number = 122;
            user.UserName = "u";
            user.Id = 1;
    
            session.Save(user);
            User user1 = session.CreateCriteria<User>().Add(Restrictions.Eq("UserName", "u")).UniqueResult<User>();
    
            session.Flush();
    

    首先从 CreateCriteria 执行 Select,然后在 Flush 插入时执行。所以这就是它没有找到任何东西的原因。

    我还使用Get&lt;User&gt;(1) 进行了测试,它返回传递给 Save 方法的实体 - 不执行任何查询。

    仍然 - 为什么要查询数据库,因为那里有实体?

    另外,你说你使用 Get 然后说你想通过 UserName 加载 - UserName 是主键吗? Get 尝试按主键加载。

    【讨论】:

    • 来自 Ayende 博客 (ayende.com/Blog/archive/2009/04/30/…):“获取通常会导致对数据库进行选择,但它会首先检查会话缓存和二级缓存以首先获取值。”我认为这意味着如果你有一个 Save() 和 Get() 一个接一个地为同一个实体它不应该击中数据库,但我还没有花时间测试。
    • hmm.. 你可能是对的 - 但我仍然不明白为什么当你有实体时调用 get 。
    • 是的,我认为需要更多信息。
    • 仍然 - 为什么要查询数据库,因为那里有实体?好吧,因为这一切都是与我的自定义 asp.net Membership 提供程序一起发生的......这是一个注册新用户的用例......当你注册一个新用户时,你将它保存到数据库并返回 Membership 用户对象回到寄存器控制。之后,控件立即调用成员资格提供程序的验证方法,仅传递用户名和密码以验证用户(登录他)。您使用该用户名和密码来加载您刚刚保存的用户对象。
    • 它正在查询数据库,因为您不是在实体的 id 上进行查询,而是在用户名/密码上进行查询。 NH必须去分贝。听起来像“注册”和“验证”的另一件事应该是它们自己的工作单元包装在事务中(或至少是刷新)。
    【解决方案2】:

    如果您的 Save 和 Get 是从不同的会话完成的,那么 Get 将返回 null,因为该对象仅存在于其他会话的内部缓存中,直到它被刷新。

    我不确定二级缓存是否会有所作为(如果二级缓存是在保存或刷新时写入的,我不确定)。

    【讨论】:

    • 我进入调试模式并检查了会话 ID(在保存和获取时),它们是相同的。
    • odd... 必须做一些测试才能知道什么是有意义的。
    猜你喜欢
    • 1970-01-01
    • 2011-04-15
    • 2010-11-17
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    相关资源
    最近更新 更多