2

我有一个简单的订单服务,想实现缓存。这是我的请求/响应和服务:

[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,我可以删除给定类型的所有项目吗?否则,如果我修改订单,我将不知道要删除哪些缓存对象。

4

1 回答 1

1

cacheKey 没有什么特别或重要的,它只需要对您要缓存的每个不同项目或结果集都是唯一的。

如果您希望它支持指定日期范围的不同缓存,则需要将变量信息添加到键中。您可以在请求 DTO 上使用唯一属性的组合,或者如果它适合base.Request.PathInfo和/或 QueryString 来创建唯一字符串以用作缓存键。

其次,如果我的缓存包含许多相同类型的对象,即 OrderResponse,我可以删除给定类型的所有项目吗?

不,每个CacheProvider都不知道缓存的内容,缓存失效逻辑由客户端应用程序管理。

否则,如果我修改订单,我将不知道要删除哪些缓存对象。

是的,在这种情况下,您要么必须设置一个过期时间,让它自己过期,要么使用底层缓存提供程序的任何高级特性(如果它们支持的话)。例如,如果您使用MemoryCacheClient支持通配符 API:

 cache.RemoveByPattern("cache:Orders:*");
 cache.RemoveByRegex("cache:Orders:.*);

因此,如果您使用相同的前缀分层构建密钥,则可以使用单个通配符命令使所有相关缓存无效。

于 2013-01-29T05:42:27.290 回答