2010-02-28 18 views
5

Sto riscontrando un comportamento strano dalla memorizzazione nella cache di Nhibernate e non riesco a capire il ragionamento. Io non sono in grado di memorizzare nella cache le query quando facendo operazioni di selezione comeproblema di nibernazione della cache con le query di linq

query.Select(x=>x).ToList() 

ma può memorizzare nella cache quando si fa:

var query = session.Linq<Promoter>(); 
var p = query.ToList(); 

Entrambi producono la stessa query SQL e deve essere doign la stessa cosa. Il seguente test spiega il problema.

[Test] 
    public void Can_Use_Cache() 
    { 
     ISessionFactory factory = Storage.Application.Get<ISessionFactory>("SessionFactory"); 
     // initial hit on the database and load into cache - all fine 
     using (var session = factory.OpenSession()) 
     { 
      Console.WriteLine(""); 
      Console.WriteLine("First Query"); 
      var query = session.Linq<Promoter>(); 
      query.QueryOptions.SetCachable(true); 
      query.QueryOptions.SetCacheMode(CacheMode.Normal); 
      var p = query.ToList(); 
     } 
     // no hit on the database and retrieved from cache as expected - all fine 
     using (var session = factory.OpenSession()) 
     { 
      Console.WriteLine(""); 
      Console.WriteLine("Second Query"); 
      var query = session.Linq<Promoter>(); 
      query.QueryOptions.SetCachable(true); 
      query.QueryOptions.SetCacheMode(CacheMode.Normal); 
      var p = query.ToList(); 
     } 
     // hits the db - should have come from the cache - not working 
     using (var session = factory.OpenSession()) 
     { 
      Console.WriteLine(""); 
      Console.WriteLine("Third Query"); 
      var query = session.Linq<Promoter>(); 
      query.QueryOptions.SetCachable(true); 
      query.QueryOptions.SetCacheMode(CacheMode.Normal); 
      var p = query.Select(x=>x).ToList(); 
     } 
     // hits the db again - should have come from the cache - again not working 
     using (var session = factory.OpenSession()) 
     { 
      Console.WriteLine(""); 
      Console.WriteLine("Fourth Query"); 
      var query = session.Linq<Promoter>(); 
      query.QueryOptions.SetCachable(true); 
      query.QueryOptions.SetCacheMode(CacheMode.Normal); 
      var p = query.Select(x => x).ToList(); 
     } 
    } 

I risultati del mio test mostrano l'hit sul db per la seconda query. interroga 3 e 4 non deve essere colpendo il db:

2010-02-28 12:05:23,046 INFO Started Logging 

First Query 
2010-02-28 12:05:23,156 DEBUG SELECT this_.Id as Id11_0_, this_.Version as Version11_0_, this_.Name as Name11_0_ FROM Promoters this_ 
NHibernate: SELECT this_.Id as Id11_0_, this_.Version as Version11_0_, this_.Name as Name11_0_ FROM Promoters this_ 

Second Query 

Third Query 
2010-02-28 12:05:23,315 DEBUG SELECT this_.Id as Id11_0_, this_.Version as Version11_0_, this_.Name as Name11_0_ FROM Promoters this_ 
NHibernate: SELECT this_.Id as Id11_0_, this_.Version as Version11_0_, this_.Name as Name11_0_ FROM Promoters this_ 

Fourth Query 
2010-02-28 12:05:23,318 DEBUG SELECT this_.Id as Id11_0_, this_.Version as Version11_0_, this_.Name as Name11_0_ FROM Promoters this_ 
NHibernate: SELECT this_.Id as Id11_0_, this_.Version as Version11_0_, this_.Name as Name11_0_ FROM Promoters this_ 

La cache è configurato utilizzando fluente:

SessionFactory = Fluently.Configure() 
      .Database(MsSqlConfiguration.MsSql2008 
          .ConnectionString(ConfigurationService.SqlConnectionString) 
          .ShowSql() 
         .Cache(c => c 

            .UseQueryCache() 
            .ProviderClass(typeof(NHibernate.Cache.HashtableCacheProvider).AssemblyQualifiedName)) 
         ) 
      .Mappings(m => m.FluentMappings.AddFromAssemblyOf<EventMap>() 
           .Conventions.Setup(MappingConventions.GetConventions())) 
      .ExposeConfiguration(BuildSchema) 
      .BuildSessionFactory(); 

risposta

2

sembra essere un problema con l'utilizzo .Select() come in .Select (x = > x) Per qualche motivo, la cache viene bypassata quando si utilizza la selezione. Eventuali altre dichiarazioni funzionano bene come OrderBy(), Dove() ecc

codice di esempio riportato di seguito:

using (var session = factory.OpenSession()) 
      { 
       Console.WriteLine(""); 
       var query = session.Linq<Promoter>(); 
       query.QueryOptions.SetCachable(true); 
       query.QueryOptions.SetCacheMode(CacheMode.Normal); 
       var p = query.OrderBy(x => x.Name).ToList();// works fine 
       //var p = query.OrderBy(x => x.Name).Select(x=>x).ToList();// will hit the db 
      } 
Problemi correlati