NHibernate 使用 SysCache 跨会话缓存实体

发布于 2024-09-27 18:52:46 字数 1694 浏览 5 评论 0 原文

我正在开发一个 Web 应用程序,我希望缓存能够跨 Web 请求持续存在。 我知道一级缓存仅适用于每个会话。我启用了二级缓存,这适用于查询。

然而,二级缓存似乎不适用于“获取”实体……因此应用程序执行的大部分数据库工作都不会跨 Web 请求进行缓存。

这是正常/理想的行为吗?我正在审查一个特定的页面,该页面对数据库进行大量往返,尽管每个查询都很快,但如果可以缓存实体,这些似乎是不必要的。

编辑

好的,我启用了二级缓存,并用于查询。我似乎无法让它为实体工作。我正在测试的主要实体上有 Cache.Is(c => c.ReadWrite()) (流畅的 nhibernate)。但不,它每次仍然会访问数据库。有什么想法吗?

编辑

我尝试过使用这样的事务:

public override Accommodation Get(int id) 
{ 
    using (var tx = Session.BeginTransaction()) 
    { 
        var accomm = Session.Get<Accommodation>(id); 
        tx.Commit(); 
        return accomm; 
    } 
} 

我的映射是这样的(你可以看到我们有一个令人讨厌的模式):

public void Override(AutoMapping<Core.Entities.Itinerary.Accommodation.Accommodation> mapping)
{
    mapping.HasManyToMany(x => x.Features).Table("AccommodationLinkFeatureType").ChildKeyColumn("FeatureTypeId").NotFound.Ignore();
    mapping.HasManyToMany(x => x.SimilarAccommodation).Table("AccommodationLinkSimilarAccommodation").ChildKeyColumn("SimilarAccommodationId").NotFound.Ignore();
    mapping.HasMany(x => x.TourItinerary).Table("AccommodationTourItinerary");
    mapping.HasOne(x => x.Images).ForeignKey("AccommodationId").Cascade.All().Not.LazyLoad();
    mapping.References(x => x.CollectionType).NotFound.Ignore().Not.LazyLoad();
    mapping.References(x => x.AccommodationUnitType).NotFound.Ignore().Not.LazyLoad();
    Cache.Is(c => c.ReadWrite());
}

但是,这似乎仍然没有从二级缓存中获取。

顺便说一句,我在网上看到很多使用 Cache.ReadWrite() 的示例,但我只能在缓存助手上看到 Is 方法,所以我尝试 Cache.Is(c => c.ReadWrite()) -- 流畅的界面是否已更改?

I'm developing a web application and I would like caching to persist across web requests.
I am aware that the first level cache is per-session only. I have second-level caching enabled and this is working for queries.

However, the second-level cache does not seem to work for "getting" entities... therefore most of the DB work the application does is not being cached across web requests.

Is this normal / desirable behaviour? I'm reviewing one particular page that makes lots of round trips to the database, although each query is quick, these seem unnecessary if the entities could be cached.

Edit

Okay so I have second level cache enabled, and working for queries. I just can't seem to get it working for entities. I have Cache.Is(c => c.ReadWrite()) (fluent nhibernate) on my main entity that I'm testing. But nope, it still hits the DB each time. Any ideas?

Edit

I've tried using transactions like so:

public override Accommodation Get(int id) 
{ 
    using (var tx = Session.BeginTransaction()) 
    { 
        var accomm = Session.Get<Accommodation>(id); 
        tx.Commit(); 
        return accomm; 
    } 
} 

My mapping is such (and you can see we have a nasty schema):

public void Override(AutoMapping<Core.Entities.Itinerary.Accommodation.Accommodation> mapping)
{
    mapping.HasManyToMany(x => x.Features).Table("AccommodationLinkFeatureType").ChildKeyColumn("FeatureTypeId").NotFound.Ignore();
    mapping.HasManyToMany(x => x.SimilarAccommodation).Table("AccommodationLinkSimilarAccommodation").ChildKeyColumn("SimilarAccommodationId").NotFound.Ignore();
    mapping.HasMany(x => x.TourItinerary).Table("AccommodationTourItinerary");
    mapping.HasOne(x => x.Images).ForeignKey("AccommodationId").Cascade.All().Not.LazyLoad();
    mapping.References(x => x.CollectionType).NotFound.Ignore().Not.LazyLoad();
    mapping.References(x => x.AccommodationUnitType).NotFound.Ignore().Not.LazyLoad();
    Cache.Is(c => c.ReadWrite());
}

However, this still doesn't seem to fetch from the 2nd level cache.

Incidentally, I see a lot of examples online using Cache.ReadWrite() but I can only see an Is method on the Cache helper, so I'm trying Cache.Is(c => c.ReadWrite()) -- has the fluent interface changed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

死开点丶别碍眼 2024-10-04 18:52:47

我没有对此进行测试,但我的理解是提交事务是将对象放入二级缓存的魔法。如果您在事务之外执行读取操作,则对象将不会放置在二级缓存中。

I have not tested this, but my understanding is that committing transactions is the magic that places objects into second level cache. If you are doing read operations outside of a transaction then the objects will not be placed in the second level cache.

鲜血染红嫁衣 2024-10-04 18:52:47

我也有同样的问题。
在我的例子中,原因是引用是用 NotFound().Ignore() 映射的(即,如果没有找到带有此外键的实体,则忽略它,这实际上是一个数据一致性错误)。删除 NotFound.Ignore 并修复您的数据库。

I had the same problem.
In my case the cause was the References is mapped with NotFound().Ignore() (i.e if no entity is found with this foreign key just ignore it, which is actualy a data consistency error anyway). Remove NotFound.Ignore and fix your db.

多彩岁月 2024-10-04 18:52:47

也许您的缓存提供程序的配置存在问题。我已经能够满足您的需要,使用 Couchbase 作为二级缓存提供程序,如下所述:

http://blog.couchbase.com/introducing-nhibernate-couchbase-2nd-level-cache-provider

如果您的部署环境位于 Azure 上,我想这可能会有用。请注意,SysCache 模块不能与 AzureMemcached 模块共存。

http://www.webmoco.com/webmoco-development -blog/orchard-cms-二级缓存

Maybe you´re having some problem with the configuration of your cache provider. I´ve been able to do want you want using Couchbase as 2nd level cache provider, as described here:

http://blog.couchbase.com/introducing-nhibernate-couchbase-2nd-level-cache-provider

If your deployment enviroment is on Azure, i guess this might be useful. Note that The SysCache module can’t co-exist with the AzureMemcached module.

http://www.webmoco.com/webmoco-development-blog/orchard-cms-second-level-caching

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文