我有一个简单的Orders服务,并希望实现缓存。这是我的请求/回复和服务:
[Route("/order", "GET")]
[Route("/order/{Id}", "GET")]
public class OrderRequest : IReturn<OrderResponse>
{
public int Id { get; set; }
public string Reference1 { get; set; }
public string Reference2 { get; set; }
public DateRange CreatedOn { get; set; }
public DateRange ProcessedOn { get; set; }
public DateRange ShippedOn { get; set; }
public DateRange ModifiedOn { get; set; }
}
public class OrderResponse : IHasResponseStatus
{
public ResponseStatus ResponseStatus { get; set; }
public List<Order> Orders { get; set; }
}
public class OrdersService : Service
{
public object Get(OrderRequest request)
{
var cacheKey = UrnId.Create<OrderResponse>(request.Id.ToString());
return base.RequestContext.ToOptimizedResultUsingCache(base.Cache, cacheKey, new TimeSpan(0,5,0), () =>
{
return GetOrders(request);
});
}
public OrderResponse GetOrders(OrderRequest request)
{
..
}
}
查看文档,为每个缓存项生成唯一键。在示例中,这通常是响应对象+项ID。但是我想缓存不同类型的请求。例如,在我的请求中,我可以指定日期范围。如果我使用相同的日期范围发出相同的请求,那么我希望收到缓存的副本。所以我的问题是,基于部分或全部请求参数生成唯一ID的最佳方法是什么?也许在请求DTO上使用或覆盖GetHashCode?其次,如果我的缓存包含许多相同类型的对象,即OrderResponse,我可以删除给定类型的所有项吗?否则,如果我修改了一个订单,我将不知道要删除哪个缓存对象。
答案 0 :(得分:1)
cacheKey没有什么特别或重要的,它只需要对要缓存的每个不同项或结果集都是唯一的。
如果您希望它支持指定日期范围的不同缓存,则需要将变量信息添加到密钥。您可以在Request DTO上使用唯一属性的组合,也可以使用base.Request.PathInfo
和/或QueryString来创建用作缓存键的唯一字符串。
其次,如果我的缓存包含许多相同类型的对象,即OrderResponse,我可以删除给定类型的所有项吗?
不,每个CacheProvider都不知道缓存的内容,缓存失效逻辑由客户端应用程序来管理。
否则,如果我修改了一个订单,我将不知道要删除哪个缓存对象。
是的,在这种情况下,您必须放置到期,以使其自身过期或使用底层缓存提供程序的任何高级功能(如果它们支持它)。例如。如果您使用MemoryCacheClient
支持通配符API:
cache.RemoveByPattern("cache:Orders:*");
cache.RemoveByRegex("cache:Orders:.*);
因此,如果使用相同的前缀按层次结构构建密钥,则可以使用单个通配符命令使所有相关的高速缓存无效。