在.NET Core Web Api中使用redis

1. 引入 Redis 依赖

在 Water.Api 项目中安装 Redis 客户端包:右键项目 → 管理 NuGet 包 → 安装 StackExchange.Redis(主流 Redis 客户端)。

2. 配置 Redis 连接在

appsettings.json 中添加 Redis 连接字符串:

cs 复制代码
{
  "ConnectionStrings": {
    "DefaultConnection": "数据库连接字符串",
    "Redis": "localhost:6379,password=你的密码,defaultDatabase=0" // Redis 连接串 没有设置密码就删除password选项
  }
}

3. 注册 Redis 服务(Program.cs)

cs 复制代码
using StackExchange.Redis;

// 注册 Redis 连接
builder.Services.AddSingleton<IConnectionMultiplexer>(sp =>
{
    var configuration = builder.Configuration.GetConnectionString("Redis");
    return ConnectionMultiplexer.Connect(configuration);
});

4:改造业务层(添加缓存逻辑)在

WaterInfoService 中注入 Redis 并实现 "先查缓存、再查数据库、后写缓存" 的逻辑:

cs 复制代码
using AutoMapper;
using StackExchange.Redis;
using System.Text.Json;
using Water.Application.Contracts.WaterInfo;
using Water.Application.Contracts.WaterInfo.Dtos;
using Water.Application.Contracts.WaterInfo.Vos;
using Water.Domain.Repositories;
using Microsoft.Extensions.Logging;

namespace Water.Application.WaterInfo.Services;

public class WaterInfoService : IWaterInfoService
{
    private readonly IWaterInfoRepository _waterInfoRepository;
    private readonly IMapper _mapper;
    private readonly IDatabase _redisDb;
    private readonly ILogger<WaterInfoService> _logger;
    private const string CachePrefix = "water:info:list:";
    private const int CacheExpirySeconds = 300; // 缓存过期时间(5分钟)

    public WaterInfoService(
        IWaterInfoRepository waterInfoRepository, 
        IMapper mapper,
        IConnectionMultiplexer redisMultiplexer,
        ILogger<WaterInfoService> logger)
    {
        _waterInfoRepository = waterInfoRepository;
        _mapper = mapper;
        _redisDb = redisMultiplexer.GetDatabase();
        _logger = logger;
    }

    public async Task<List<WaterInfoListVo>> GetWaterInfoListAsync(WaterInfoQueryDto waterInfoQueryDto)
    {
        string cacheKey;

        // 生成缓存键(区分"全部商品"和"按分类查询")
        if (waterInfoQueryDto.CategoryId.HasValue)
        {
            cacheKey = $"{CachePrefix}category:{waterInfoQueryDto.CategoryId.Value}";
        }
        else
        {
            cacheKey = $"{CachePrefix}all";
        }

        try
        {
            // 尝试从 Redis 读取缓存
            var cachedData = await _redisDb.StringGetAsync(cacheKey);
            if (!cachedData.IsNull)
            {
                return JsonSerializer.Deserialize<List<WaterInfoListVo>>(cachedData)!;
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Redis 查询失败,降级到数据库查询");
            // 异常时继续执行数据库查询逻辑
        }

        // 缓存不存在,查询数据库
        var domainEntities = await _waterInfoRepository.GetWaterInfoListAsync(
            categoryId: waterInfoQueryDto.CategoryId,
            name: waterInfoQueryDto.Name
        );
        var voList = _mapper.Map<List<WaterInfoListVo>>(domainEntities);

        // 仅当未传"商品名称"时,才写入缓存(模糊查询不缓存)
        if (string.IsNullOrEmpty(waterInfoQueryDto.Name))
        {
            await _redisDb.StringSetAsync(
                key: cacheKey,
                value: JsonSerializer.Serialize(voList),
                expiry: TimeSpan.FromSeconds(CacheExpirySeconds)
            );
        }

        return voList;
    }
}

5:处理缓存失效(可选,数据更新时清理缓存)

当商品数据发生变更(新增、修改、删除)时,需主动删除对应缓存,示例(假设存在修改方法):

cs 复制代码
// 在 WaterInfoService 中新增修改方法(示例)
public async Task<bool> UpdateWaterInfoAsync(WaterInfoUpdateDto updateDto)
{
    // 1. 执行数据库修改逻辑(略)
    var isSuccess = await _waterInfoRepository.UpdateAsync(updateDto);

    // 2. 删除缓存(确保下次查询获取最新数据)
    var cacheKeys = new List<string> { $"{CachePrefix}all" }; // 先删除"全部商品"缓存
    if (updateDto.CategoryId.HasValue)
    {
        cacheKeys.Add($"{CachePrefix}category:{updateDto.CategoryId.Value}"); // 再删除"对应分类"缓存
    }
    foreach (var key in cacheKeys)
    {
        await _redisDb.KeyDeleteAsync(key);
    }

    return isSuccess;
}
相关推荐
偶尔的鼠标人5 小时前
SqlSugar查询字符串转成Int的问题
c#·sqlsugar
我不是程序猿儿5 小时前
【C#】WinForms 控件句柄与 UI 刷新时机
开发语言·ui·c#
祈祷苍天赐我java之术6 小时前
如何在Java中整合Redis?
java·开发语言·redis
星梦清河7 小时前
Redis(四):缓存击穿及其解决方案(SpringBoot+mybatis-plus)
spring boot·redis·缓存
傻啦嘿哟8 小时前
用Redis实现爬虫URL去重与队列管理:从原理到实战的极简指南
数据库·redis·爬虫
聪明努力的积极向上9 小时前
【C#】HTTP中URL编码方式解析
开发语言·http·c#
@爱学习的小趴菜11 小时前
Redis服务器配置
服务器·数据库·redis
关关长语11 小时前
(四) Dotnet中MCP客户端与服务端交互通知日志信息
ai·c#·mcp
小码编匠11 小时前
WPF 动态模拟CPU 使用率曲线图
后端·c#·.net