【发布时间】:2016-02-13 21:25:07
【问题描述】:
我们的项目使用 Entity Framework 并有 2 种类型的缓存(内存中,Redis),没有任何缓存提供程序。由于lack of second-level cache support in EF,我们自己实现了它。所以我们的内存缓存是一组简单的键值对,其中键是缓存的 ID,值是缓存的对象。我们还实现了类似的缓存来使用 Redis。对于查询,我们查看内存缓存列表,如果不存在,我们查看 redis,如果不存在,我们查询数据库。
因为实体框架实体引用了上下文,我们不能在缓存中使用DbContext的实体,我们需要映射它。所以我们需要创建很多 DTO。
我知道缓存是cross-cutting concern,所以我寻找更清洁的解决方案。出于这个原因,首先我决定将Memcached 用于 In-Memory(而不是使用简单列表)。其次,也是最重要的,我可能会从 EF 迁移到 NHibernate,以获得对 Second-Cache 的支持。我知道first level cache is occupied by session object。所以我想用 Memcached 做二级缓存。但是Redis有没有三级缓存呢?
【问题讨论】:
-
关于 DTO 您在使用(DbContext 的)代理实体时遇到问题吗?通常,当您尝试访问未加载的相关属性时会出现问题,因为延迟加载器无法访问已处置的上下文,但您对分离的实体有相同的问题(在这两种情况下,您都需要使用 Include)。再次关于 DTO,我始终实现 Clone 开始实现浅克隆(但它取决于实体)并且通常(始终)是字段值副本(使用类似于 MemberwiseClone 但不是 MemberwiseClone 的自定义函数,否则您将再次拥有整个代理)。
-
@bubi 我不想为了持久性框架而损害我的域模型。创建 DTO 类似于 Momento 模式。其次,我想要一个实体框架没有的好的缓存提供程序。
-
您不会使用上述方法破坏模型。我认为你做到了,但如果你没有,你可以看看 EF 的二级缓存实现。关于 Hibernate 我建议您尝试一下,如果您的目的可以正常工作。我可以说现在(对于新项目)我正在使用 EF,而旧项目仍处于休眠状态。 Hibernate 的问题是您经常需要很早就实现查询。如果您认为经常/总是在内存中工作,它可以正常工作,但如果您需要在 DB 上工作,您有时需要编写 HQL 或 SQL(或在查询的早期插入 ToList())。
-
@bubi 您能否在回答帖子中详细说明?还是谢谢。
标签: entity-framework hibernate caching nhibernate redis