You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web API中IDistributedCache异步Get方法缓存实现求助

实现分布式缓存逻辑的方案

咱们可以按照「先读缓存,缓存未命中再查数据库并写入缓存」的经典逻辑来实现,结合IDistributedCache的异步方法完成改造。下面是具体的代码和细节说明:

完整改造后的代码

using System.Text;
using System.Text.Json;

public class SvcBooking
{
    private readonly DbContextSMATA _ctx;
    private readonly IMapper _mapper;
    private readonly IDistributedCache _cache;
    // 定义专属缓存键,建议加业务前缀避免键冲突
    private const string _allBookingsCacheKey = "BusinessPrefix_AllBookings";

    public SvcBooking(DbContextSMATA ctx, IMapper mapper, IDistributedCache cache)
    {
        _ctx = ctx;
        _mapper = mapper;
        _cache = cache;
    }

    public async Task<IList<IDtoBooking>> GetAll()
    {
        // 1. 先尝试从分布式缓存获取数据
        var cachedBookingsJson = await _cache.GetStringAsync(_allBookingsCacheKey);
        
        if (!string.IsNullOrEmpty(cachedBookingsJson))
        {
            // 缓存命中:反序列化为实体列表,再映射成DTO返回
            var cachedBookings = JsonSerializer.Deserialize<IList<Booking>>(cachedBookingsJson);
            return _mapper.Map<IList<IDtoBooking>>(cachedBookings);
        }

        // 2. 缓存未命中:查询数据库获取最新数据
        var dbBookings = await _ctx.Set<Booking>().ToListAsync();
        
        // 3. 将数据库结果序列化后写入缓存,同时设置过期策略
        var bookingsJson = JsonSerializer.Serialize(dbBookings);
        var cacheOptions = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromMinutes(30)); // 滑动过期:30分钟无访问则自动失效
        
        await _cache.SetStringAsync(_allBookingsCacheKey, bookingsJson, cacheOptions);

        // 4. 映射为DTO返回给调用方
        return _mapper.Map<IList<IDtoBooking>>(dbBookings);
    }
}

关键细节提醒

  • 缓存键命名:用固定的常量标识缓存项,加上业务前缀能避免和其他模块的缓存键冲突。
  • 序列化方案:示例用了.NET内置的System.Text.Json,如果项目用的是Newtonsoft.Json,替换对应的序列化/反序列化方法即可(记得安装对应NuGet包)。
  • 过期策略:这里用了滑动过期,适合访问频率不稳定的场景;如果需要固定过期时间,可以用SetAbsoluteExpiration(TimeSpan.FromHours(2)),也可以同时设置两种过期策略(以先触发的为准)。
  • 异常降级(可选):如果担心缓存服务故障影响业务,可以给缓存操作套个try-catch,当缓存读写失败时直接走数据库逻辑,同时记录异常日志:
    try
    {
        var cachedBookingsJson = await _cache.GetStringAsync(_allBookingsCacheKey);
        // ... 缓存命中逻辑
    }
    catch (Exception ex)
    {
        // 日志记录示例,需要注入ILogger
        _logger.LogError(ex, "读取预订缓存失败,将直接查询数据库");
    }
    
  • 缓存失效机制:当预订数据有增删改操作时,记得调用await _cache.RemoveAsync(_allBookingsCacheKey);清空旧缓存,避免返回过时数据。

内容的提问来源于stack exchange,提问作者Gani Lastra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:51:51