实体框架和 NHibernate - 缓存仍然是服务层的责任吗?

Posted

技术标签:

【中文标题】实体框架和 NHibernate - 缓存仍然是服务层的责任吗?【英文标题】:Entity Framework and NHibernate - Is caching still a service layer responsibility? 【发布时间】:2011-02-08 22:51:56 【问题描述】:

在使用 ORM 之前,我们总是在服务层中执行对象缓存。这使我们能够在不同的数据层之间切换,而无需更改我们的缓存实现。

现在我们同时使用实体框架(主要是代码优先)和 NHibernate。 NHibernate 似乎有更好的缓存功能,有几个可用的二级缓存提供程序。

我面临的另一个问题是,对于上述两个 ORM,我们都使用了延迟加载的属性。因此,如果我们从缓存中检索对象,我们通常必须将其重新附加到当前的 ObjectContext/ISession,而这在我们的服务层中实际上是无法做到的。

所以我真的应该考虑在存储库/数据层实现缓存吗?是否有可能找到适用于 EF 和 NH 的通用解决方案?

谢谢 本

【问题讨论】:

【参考方案1】:

你看过CQRS pattern吗?因为caching is policy,我怀疑尝试使用“一刀切”的缓存(如第二层缓存)来自动化这些决策。例如,如果您真正想要缓存的是网站主页的 html,那么第二层缓存只是浪费内存并招致 bug。

CQRS 将这些机械考虑因素转化为政策决策。它与 ORM 无关。

【讨论】:

嗨,克雷格,感谢您的链接。 Udi 的视频确实帮助我掌握了这一点 (bit.ly/d29jZU)。根据您的经验,CQRS 是否适用于网络/电子商务应用程序,尤其是在您的视图可能包含“陈旧”(产品信息)、个性化(购物车、个人资料)和实时(以及尽可能实时的视图,例如库存)的情况下水平)数据。 Udi 还谈到了在出现问题时传递命令并发出异步响应——这在 Web 应用程序中通常不容易实现。 嗯,amazon.com 开创了这个东西(“最终一致”),所以是的,我会说它对电子商务来说是可行的。显然,您必须选择哪些可以过时,哪些不能。但关键是这是一项业务,而不是技术方面的考虑。 它是可以添加到现有应用程序中的,还是我们真的应该在开始编写任何代码之前做出这样的架构决策?显然,可以随时添加诸如 http 缓存之类的功能,而不会产生重大影响。 无论如何,除了由于不正确的缓存过期策略导致站点损坏之外,没有其他重大影响。虽然最好从一开始就构建它,但如果你小心的话,可以逐个添加缓存。配置文件,找到性能热点,设计正确的缓存策略,并将其添加到就在那个地方。 疯狂地测试,然后从那里成长。与第二层缓存不同,您可以轻松地一次在一个地方执行此操作,从而限制 QA 范围。 我对 CQRS 的研究越多,它看起来就越有说服力。感谢您打开我的眼睛。现在,去了解更多:)【参考方案2】:

我的经验是 ORM 提供的二级缓存会根据从数据库中检索到的实际结果集来缓存数据。这会给您带来很多开销,因为对象实例化和数据填充非常昂贵。

优点是延迟加载等可以正常工作,但大结果在重新填充对象时仍然会占用大量资源。

我们在 Web 应用程序中使用二级缓存和 ASP.NET 缓存的组合,因为开销很大,在极少数情况下可以为我们节省多达几秒钟(!),但缺点是无法延迟加载集合或更新实体。

这仅基于 NHibernate,我从未使用过实体框架,但我猜所有的 ORM 框架都会受此影响。

【讨论】:

以上是关于实体框架和 NHibernate - 缓存仍然是服务层的责任吗?的主要内容,如果未能解决你的问题,请参考以下文章

代码优先实体框架或 NHibernate

ADO.NET 实体框架与 NHibernate [关闭]

实体框架与 NHibernate - 性能

选择实体框架作为针对 Nhibernate 的默认实现 ORM,利弊?

在实体框架中更新实体的最佳方法[重复]

Nhibernate 与其他 ORM 的区别是啥?