Надеюсь на вашу помощь. У меня есть простые наборы мастера-ребенка («игрок» и «playerChildObject»). Извлечение «игроков» также позволяет связанным детям.NHibernate SysCache не кэширует дочерние объекты
SysCache кэширует игроков, однако не кэширует детей.
Вот объекты (как набор с Cache.ReadWrite()):
Сущности:
public class Player
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<PlayerChildObject> PlayerChildObjects { get; set; }
public Player()
{
PlayerChildObjects = new List<PlayerChildObject>();
}
}
public class PlayerChildObject
{
public virtual int Id { get; protected set; }
public virtual Player Player { get; set; }
}
Mapping:
public class PlayerMap : ClassMap<Player>
{
public PlayerMap()
{
Id(x => x.Id).Column("id");
Map(x => x.Name).Column("name");
HasMany(x => x.PlayerChildObjects).KeyColumn("PlayerId")
.Inverse()
.Cascade.All()
.Not.LazyLoad();
Table("accounts");
Cache.ReadWrite();
}
}
public class PlayerChildObjectMap : ClassMap<PlayerChildObject>
{
public PlayerChildObjectMap()
{
Id(x => x.Id).Column("id");
References<Player>(x => x.Player, "playerId");
Table("playerChildObjects");
Cache.ReadWrite();
}
}
Session завод также с "UseQueryCache" и «UseSecondLevelCache»:
Fluently.Configure()
.Database(MySQLConfiguration.Standard.ConnectionString(cs => ...))
.Cache(c => c.UseQueryCache().UseSecondLevelCache()
.ProviderClass(typeof (NHibernate.Caches.SysCache.SysCacheProvider).AssemblyQualifiedName))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<PlayerChildObjectMap>())
.BuildSessionFactory();
И сам запрос с SetCacheable (истина) .SetCacheMode (CacheMode.Normal):
using (var session = SessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
players = session.CreateCriteria(typeof(Player))
.SetCacheable(true)
.SetCacheMode(CacheMode.Normal)
.List<Player>();
transaction.Commit();
}
}
Однако профайлер показывает, что игроки кэшируются (называется только первый раз игроки выполнения выборки коды), в то время как тот же PlayerChildObjects каждый раз извлекаются с помощью PlayerID.
Итак, первый запрос дает N + 1 DB-вызовы (список игроков + дочерние объекты каждым игроком), все последовательные запросы выполняют N вызовов (дочерние объекты по каждому игроку).
Что мне не хватает? Как сделать кеширование SysCache детьми?
версия SysCache: 3.1.0.4000
Я надеюсь, что эта магия работает. Собираюсь проверить его сегодня вечером. –
Он делает! До сих пор я пропускал партии, так как ожидал не более 10 детей для каждого игрока. Но эта строка сделала это: 'HasMany (x => ......). Cache.IncludeAll(). ReadWrite();' Danke! –
Замечательно видеть, что сэр! ;) Наслаждайтесь могучим NHiberante;) –