在.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;
}
相关推荐
Charles_go9 分钟前
C#中级45、什么是组合优于继承
开发语言·c#
我是唐青枫27 分钟前
一文理解 C#.NET Tuples:从基础到高级应用
c#·.net
Charles_go1 小时前
C#中级46、什么是模拟
开发语言·oracle·c#
一只爱做笔记的码农1 小时前
【BootstrapBlazor】移植BootstrapBlazor VS工程到Vscode工程,报error blazor106的问题
笔记·学习·c#
q***18844 小时前
Ubuntu上安装、使用Redis的详细教程
redis·ubuntu·bootstrap
q***65694 小时前
Windows环境下安装Redis并设置Redis开机自启
数据库·windows·redis
q***47434 小时前
Windows 和 Linux 系统下,如何查看 Redis 的版本号?
linux·windows·redis
q***96584 小时前
Windows版Redis本地后台启动
数据库·windows·redis
利刃大大4 小时前
【c++中间件】redis介绍 && redis-plus-plus库使用
c++·redis·中间件
q***81644 小时前
【Redis】centos7 systemctl 启动 Redis 失败
数据库·redis·缓存