【问题标题】:nHibernate Session.Load by property namenHibernate Session.Load 按属性名称
【发布时间】:2011-02-04 15:33:43
【问题描述】:

我的 DTO 有一个我的数据库使用的 ID,通常是一个自动递增的 INT。一般来说,我的应用程序从不关心这个 ID 字段,它倾向于通过它们的 Name 属性来查找 DTO。在我的数据访问层中产生了这种方法:

public T GetByName(string name)
{
    return (T) Session
        .CreateCriteria(typeof (T))
        .Add(Expression.Eq("Name", name))
        .UniqueResult();
}

现在,我注意到,由于这是我加载绝大多数 DTO 的方式,nHibernate 没有缓存结果。我已经能够通过 SQL Profiler 观察到,每次调用这个方法都会导致到数据库的往返,即使我确定我在我的工作单元期间加载了这个特定的对象(一个HTTP 事务)。

此外,我读到的是,当您调用 .Load() 时,nHibernate 会将 DTO 缓存在一级缓存中。

所以,我的问题是:有没有办法配置 nHibernate 以在以这种方式加载后将我的 DTO 放入一级缓存,或者我是否需要找到另一种方法来减少我的数据库往返?

【问题讨论】:

    标签: nhibernate


    【解决方案1】:

    您的代码存在几个问题。

    1. 条件将始终转到数据库,除非您缓存查询。您需要使用SetCacheable,配置缓存提供程序和enable query caching
    2. 即使您缓存查询,您仍然需要make the entity cacheable,因为 NHibernate 存储该查询产生的对象 ID,而不是实体本身。
    3. 所谓的“一级缓存”就是工作单元(会话)。您使用GetLoad 方法与它进行交互,而不是查询。小例外:会话中已经加载的实体不需要再次从数据库中读取。

    【讨论】:

      【解决方案2】:

      NHibernate 不会在一级缓存中缓存您的实体,除非您通过它们的主键加载它们。

      前段时间我也遇到过同样的情况。我从来没有确定不是由主键加载的实体是否会缓存在二级缓存中(如果您使用的是二级缓存)。也许其他人可以提供答案。

      【讨论】:

      • 二级缓存中缓存的内容由二级缓存配置决定。在这种情况下,需要打开查询结果缓存,因为您实际上是在执行查询来检索对象。
      【解决方案3】:

      如果将 natural-id 定义为 name 字段会怎样?我不知道 nHibernate 是否只会将其用于模式生成,但这是有道理的,这是定义它的自然位置,无论 nHibernate 实际将如何处理它。如果没有,这不是一个糟糕的功能请求。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-03
        • 2010-09-25
        相关资源
        最近更新 更多