首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate SysCache不缓存子对象。

NHibernate SysCache不缓存子对象。
EN

Stack Overflow用户
提问于 2015-04-16 07:20:01
回答 1查看 250关注 0票数 2

希望得到你的帮助。我有简单的主子集("player“和"playerChildObject")。抓取“玩家”也会把他们联系在一起的孩子带走。

SysCache缓存玩家,但是不缓存子缓存。

下面是对象(都是用Cache.ReadWrite()设置的):

实体:

代码语言:javascript
复制
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; }
}

制图:

代码语言:javascript
复制
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();
    }
}

会话工厂还带有"UseQueryCache“和"UseSecondLevelCache":

代码语言:javascript
复制
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(true).SetCacheMode(CacheMode.Normal):查询本身

代码语言:javascript
复制
using (var session = SessionFactory.OpenSession())
{
    using (var transaction = session.BeginTransaction())
    {
        players = session.CreateCriteria(typeof(Player))
            .SetCacheable(true)
            .SetCacheMode(CacheMode.Normal)
            .List<Player>();
        transaction.Commit();
    }
}

但是,分析器显示,播放机被缓存(只被称为第一次执行播放器获取代码),而PlayerID每次都会检索相同的PlayerID。

因此,第一个请求给出了N+1 DB调用(每个播放器都有一个播放器+子对象列表),所有连续的请求都执行N个调用(每个播放器执行子对象)。

我错过了什么?如何也使SysCache缓存子级?

SysCache版本: 3.1.0.4000

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-16 08:26:14

我想说,有两个问题。首先,即使是one-to-many (HasMany)也有缓存设置:

代码语言:javascript
复制
HasMany(x => x.PlayerChildObjects).KeyColumn("PlayerId")
    ...
    .Cache.IncludeAll() // or .IncludeNonLazy, .CustomInclude("customInclude")
        .ReadOnly() // or .NonStrictReadWrite(), .ReadWrite(), .Transactional(),
                    //  .CustomUsage("customUsage")        
        .Region("regionName");

查看更多关于HasMany映射的内容(由Adam撰写的关于代码映射的文章,但最后是流利的)

19.2.1.缓存映射医生

其次,我们应该使用批取:

代码语言:javascript
复制
public PlayerMap()
{
    BatchSize(25);

    HasMany(x => x.PlayerChildObjects).KeyColumn("PlayerId")
        ...
        .BatchSize(25)
...
public PlayerChildObjectMap()
{
    BatchSize(25);
    ...

在doc 19.1.5.使用批取中阅读更多关于它的内容,或者在这里:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29667925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档