2011-10-14 46 views
2

當我使用Session.Get()時,我的二級緩存工作完美,但是如果我在NH3.0中使用新的QueryOver API,緩存不會被擊中。使用QueryOver的NHibernate二級緩存問題

這完美的作品:

public TEntity Get(int id) 
{ 
    return session.Get<TEntity>(id); 
} 

這不命中cache:

public TEntity Get(Expression<Func<TEntity bool>> filter) 
{ 
    var query = _session.QueryOver<TEntity>() 
       .Where(filter); 

    query.Cacheable();  
    return query.SingleOrDefault(); 
} 

我使用的交易,以確保二級高速緩存的使用是否正確。

這裏是我的會話配置:

Session = Fluently.Configure() 
       .Database(SQLiteConfiguration.Standard.InMemory().ShowSql()) 
       .Mappings(x => x.FluentMappings.AddFromAssemblyOf<Activity>()) 
       .Cache(c => c.UseSecondLevelCache() 
          .UseQueryCache() 
          .ProviderClass<NHibernate.Cache.HashtableCacheProvider>()) 
       .ExposeConfiguration(cfg => configuration = cfg) 
       .BuildSessionFactory() 
       .OpenSession(); 

我設置我的緩存使用實體:

public class CommentMap : ClassMap<Comment> 
    { 
     public CommentMap() 
     { 
      Cache.ReadWrite(); 

      Id(x => x.Id); 
      Map(x => x.Message); 
      References(x => x.Activity); 
      References(x => x.User); 
     } 
    } 

,我號召我的QueryOver查詢可緩存方法:

public TEntity Get(Expression<Func<TEntity, bool>> filter) 
     { 
      var query = _session.QueryOver<TEntity>() 
       .Where(filter); 

      query 
       .Cacheable(); 

      return query.SingleOrDefault(); 
     } 

我一定錯過了一些東西,只是無法弄清楚什麼。

+2

請注意任何讀者!這個問題似乎已被編輯,以反映正確的實施,這就是爲什麼Diegos回答標記正確... – Konstantin

回答

6

有幾個相關問題:

  • Session.Load從未擊中DB,所以它不是一個證明,緩存工作
  • 查詢緩存從實體緩存單獨啓用
  • 查詢緩存明確:你必須告訴NHibernate使用Cacheable()方法緩存QueryOver

另外,請確保您對將要緩存的查詢的實體有實體緩存。否則緩存會讓事情變得更糟。

+0

你是對的加載只是創建代理。 –

+0

我確實已啓用查詢和實體緩存,並且我正在調用QueryOver上的Cacheable()方法。我會根據代碼檢查星期一的列表,看看我是否錯過了一些東西。謝謝。 –

+2

最後,問題是什麼?是否你有query.Cacheable(),然後返回query.SingleOrDefault()(而不是做query = query.Cacheable())?或者你找到別的東西了。 –