mfa*_*nto 11 asp.net caching repository-pattern
我开始研究ASP.NET MVC站点的缓存基础结构.问题是,我似乎找不到合理的数据缓存位置(除了"无处不在")
现在我的架构看起来像这样:
控制器 - >服务层 - >存储库.存储库使用Linq to SQL进行数据访问.
存储库公开了一些通用方法,如Insert,GetById和GetQueryable,它们返回服务层可以进一步细化的IQueryable.
我喜欢将缓存放在存储库层中的想法,因为服务层不应该真正关心数据来自何处.但问题是缓存失效.服务层有关于数据何时变得陈旧而不是存储库的更多信息.例如:
假设我们有一个Users表和一个Orders表(规范示例).服务层提供了GetOrder(int id)等方法,可以调用存储库层:
public Order GetOrder(int id)
{
using(var repo = _repoFactory.Create<Order>())
{
return repo.GetById(id)
}
}
Run Code Online (Sandbox Code Playgroud)
要么
repo.GetQueryable(order => order.Id == id && order.HasShipped == false).Single();
Run Code Online (Sandbox Code Playgroud)
如果我们在存储库层中进行缓存,那么在知道订单数据何时发生变化时,它似乎非常有限.假设用户已被删除,导致所有订单都被CASCADE删除.服务层可能使Orders缓存无效,因为它知道用户刚被删除.虽然存储库(因为它是工作单元),但是不知道.(忽略我们不应该查询已删除用户的订单这一事实,因为它只是一个例子).
在其他情况下,我认为这表明了自己.假设我们想要获取所有用户订单:
repo.GetQueryable(order => order.UserId == userId).ToList()
Run Code Online (Sandbox Code Playgroud)
存储库可以缓存此查询的结果,但是,如果添加了另一个订单,则此查询不再有效.但是只有服务层才知道这一点.
我对存储库层的理解也是错误的.我认为它是围绕数据源的外观(即从L2SQL更改为EF到任何东西,服务层不知道底层源).
实际上,你需要另一层; 数据缓存层.请求数据时,服务层将使用它.根据这样的请求,它将决定它是否具有缓存中的数据,或者是否需要查询相应的存储库.同样,您的服务层可以告知此新数据缓存层失效(删除特定用户等).
这对您的架构意味着什么,是您的数据缓存层将实现您的存储库所执行的相同接口.一个相当简单的实现将按实体类型和密钥缓存数据.但是,如果你在幕后使用更复杂的ORM(NHibernate,EF 4等),它应该有缓存作为选项.
| 归档时间: |
|
| 查看次数: |
4010 次 |
| 最近记录: |