2010-02-28 3 views
5

Je vois un comportement étrange de la mise en cache nhibernate et je ne comprends pas le raisonnement. Je ne suis pas en mesure de mettre en cache les requêtes lorsque vous effectuez des opérations de sélection commeProblème de cache nhibernate avec les requêtes linq

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

mais peut mettre en cache en faisant:

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

Les deux produisent la même requête SQL et devrait être la même chose Faire des. Le test suivant explique le problème.

[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(); 
     } 
    } 

Mes résultats de test montrant le hit sur la base de données pour la deuxième requête. interroge 3 et 4 ne doivent pas être en appuyant sur le 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_ 

Le cache est configuré en utilisant couramment:

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(); 

Répondre

2

semble être un problème avec l'utilisation .Select(), comme dans .Select (x = > x) Pour une raison quelconque, le cache est ignoré lors de l'utilisation du select. Toutes les autres déclarations fonctionnent très bien comme OrderBy(), où() etc

Exemple de code ci-dessous:

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 
      } 
Questions connexes