Nhibernate 在一个会话中加载的实体不会被缓存

Nhibernate 在一个会话中加载的实体不会被缓存,nhibernate,caching,Nhibernate,Caching,静态数据有两个实体(需要在内存中完全加载) 我打开会话并启动事务: using (var s = sessionFactory.OpenSession()) using (var tr = s.BeginTransaction()) { 我加载所有属性: s.CreateCriteria< AttributeInfo>().List().Cast< AttributeInfo>().ToArray() s.CreateCriteria().Li

静态数据有两个实体(需要在内存中完全加载)

我打开会话并启动事务:

   using (var s = sessionFactory.OpenSession())
   using (var tr = s.BeginTransaction())
   {
我加载所有属性:

   s.CreateCriteria< AttributeInfo>().List().Cast< AttributeInfo>().ToArray()
s.CreateCriteria().List().Cast().ToArray()
及所有项目:

   s.CreateCriteria< Item>().List().Cast< Item>().ToArray()
s.CreateCriteria().List().Cast().ToArray()
问题是没有使用缓存,nhibernate为每个项目创建了一个select from AttributeInfo查询

我知道静态数据加载的优化没有太大的价值。但我想了解nhibernate缓存是如何工作的


那么我做错了什么呢?

首先,您的示例对我来说很有用,而不需要为每个属性生成查询。只有在我没有加载所有属性的情况下,第二个查询当然会逐个加载所有属性,因为映射中的非惰性设置

也许您正在使用nh的旧版本,或者在其他地方有一些其他设置

无论如何,最好的方法是为非惰性集合定义获取模式

 [ManyToOne(Lazy = Laziness.False, Fetch=FetchMode.Join)]
这将强制nh创建一个连接属性查询,该查询实际上一次性解析item+属性。使用此解决方案,您不必(预先)加载所有属性,即使是您可能不需要的属性

提示:

要查看一级缓存中的元素,可以使用一个简单的扩展

public static class SessionExtensions
{
    public static IEnumerable<T> FirstLevelCache<T>(this ISession session)
    {
        ISessionImplementor impl = session.GetSessionImplementation();
        IPersistenceContext pc = impl.PersistenceContext;

        foreach (Object key in pc.EntityEntries.Keys)
        {
            if (key is T)
            {
                yield return ((T) key);
            }
        }
    }
}
公共静态类SessionExtensions
{
公共静态IEnumerable FirstLevelCache(此ISession会话)
{
ISessionImplementor impl=session.GetSessionImplementation();
IPersistenceContext pc=impl.PersistenceContext;
foreach(pc.EntityEntries.Keys中的对象键)
{
如果(键为T)
{
收益率返回((T)键);
}
}
}
}
现在

var attributes=session.CreateCriteria().List().Cast().ToArray();
var cached=session.FirstLevelCache().ToList();
缓存的
应包含属性

public static class SessionExtensions
{
    public static IEnumerable<T> FirstLevelCache<T>(this ISession session)
    {
        ISessionImplementor impl = session.GetSessionImplementation();
        IPersistenceContext pc = impl.PersistenceContext;

        foreach (Object key in pc.EntityEntries.Keys)
        {
            if (key is T)
            {
                yield return ((T) key);
            }
        }
    }
}
var attributes = session.CreateCriteria<AttributeInfo>().List().Cast<AttributeInfo>().ToArray();

var cached = session.FirstLevelCache<AttributeInfo>().ToList();