场景:我已经构建了一个管理我的烹饪食谱的ASP.NET MVC应用程序。我使用FluentNHibernate访问下表中的数据:
问题:有没有办法告诉NHibernate从上面列出的所有表中加载所有数据并将其存储在内存/ NHibernate的缓存中,这样就不必再有任何额外的数据库请求了?
问题背后的动机:多对多关系的多样性构成了一个问题,并且会从优化中受益匪浅。
有关数据的说明:数据总量非常小。我们现在谈论的食谱不到100个。
答案 0 :(得分:2)
我建议加载一次,然后在访问时保持它,而不是预加载所有内容。
NHibernate维护着两个不同的缓存,并且可以很好地保持它们与底层数据存储同步。默认情况下,它会在每个会话的基础上使用所谓的“第一级”缓存,但我不认为这是您想要的。您可以在nhibernate faq page on caching
上了解差异我怀疑你需要二级缓存(这在整个应用程序中都可用)。您需要从NHContrib获取缓存提供程序(下载与您的NHibernate版本匹配的版本)。只要您的应用程序是写入数据库的唯一内容,SysCache2提供程序可能是最容易为您的方案设置的。如果要编写其他进程,则需要确保所有进程都使用相同的缓存作为中介,如果您希望它保持同步。
第二级缓存配置了超时,您可以将其设置为您需要的任何内容。不要认为它可以是无限的,但如果你愿意,你可以将它设置为很长时间(虽然可能不是一个糟糕的想法,但不时回到DB)。如果您想预先加载所有内容,只需从global.asax的Application_Start方法访问所有实体,但这不是必需的。
您需要配置会话工厂以使用缓存。在流畅配置会话工厂时调用.Cache(...)方法,它应该是相对不言自明的。
您还需要在实体映射和关系映射中设置Cache.ReadWrite()。您可以按照惯例或通过在Fluent映射中调用Cache.ReadWrite()来执行此操作。
类似的东西:
public class RecipeMap : ClassMap<Recipe> {
public RecipeMap () {
Cache.ReadWrite();
Id(x => x.Id);
HasManyToMany(x => x.Ingredients).Cache.ReadWrite();
}
}
在映射中的Cache调用中,您可以指定ReadOnly或您可能需要的任何其他内容。 NonStrictReadWrite是一个有趣的,它可以显着提高性能,但是从缓存中读取陈旧数据的风险增加。