Проблема кеша nhibernate с запросами linq - PullRequest
5 голосов
/ 28 февраля 2010

Я вижу странное поведение от кэширования nhibernate и не могу понять причину. Я не могу кэшировать запросы при выполнении операций выбора, таких как

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

но может делать кеш при выполнении:

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

Оба производят один и тот же sql-запрос и должны быть одинаковыми. Следующий тест объясняет проблему.

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

Результаты моего теста, показывающие попадание в базу данных для второго запроса. запросы 3 и 4 не должны попадать в базу данных:

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_

Кэш настроен с использованием свободного:

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

Ответы [ 2 ]

2 голосов
/ 01 марта 2010

Кажется, проблема с использованием .Select (), как в .Select (x => x) По какой-то причине кеш обходит при использовании select. Любые другие операторы работают нормально, например OrderBy (), Where () и т. Д.

Пример кода ниже:

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
           }
0 голосов
/ 14 октября 2010

Вы пытались использовать транзакции?

http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...