nHibernate Session.Load按属性名称

时间:2011-02-04 15:33:44

标签: nhibernate

我的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事件探查器观察到,每次调用此方法都会导致数据库往返,即使我确定我已经在我的工作单元中加载了这个特定的对象( HTTP事务)。

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

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

3 个答案:

答案 0 :(得分:2)

您的代码存在一些问题。

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

答案 1 :(得分:0)

除非您通过主键加载实体,否则NHibernate不会将您的实体缓存在第一级缓存中。

我曾经有过同样的情况。我从未确定未通过主键加载的实体是否会缓存在二级缓存中(如果您使用的是)。也许其他人可以提供答案。

答案 2 :(得分:0)

如果将natural-id定义为名称字段,该怎么办?我不知道nHibernate是否只会将它用于模式生成,但是这是定义它的自然场所,而不管nHibernate实际上会用它做什么。如果没有,这不是一个糟糕的功能请求。