当前位置: 首页 > news >正文

.NET 集成 SqlSugar、读写分离 、Redis

一、环境准备(NuGet 安装)

 
# SqlSugar 核心
Install-Package SqlSugarCore
# Redis 驱动 (StackExchange.Redis 官方推荐)
Install-Package StackExchange.Redis
# 缓存工具包
Install-Package Microsoft.Extensions.Caching.StackExchangeRedis
 
 

 

二、appsettings.json 配置

 
{"ConnectionStrings": {// 主库(写入、更新、删除)"MasterDb": "Server=.;Database=TestDb;Uid=root;Pwd=123456;",// 从库(只读,可配置多个)"SlaveDb": "Server=.;Database=TestDb;Uid=root;Pwd=123456;",// Redis"Redis": "127.0.0.1:6379,password=,defaultDatabase=0"}
}
 
 

 

三、SqlSugar 读写分离配置

 

1. 注册 SqlSugar(Program.cs)

 
var builder = WebApplication.CreateBuilder(args);// 1. 注册 SqlSugar + 读写分离
builder.Services.AddSingleton<ISqlSugarClient>(provider =>
{var config = new ConnectionConfig(){// 主库ConnectionString = builder.Configuration.GetConnectionString("MasterDb"),DbType = DbType.MySql, // 根据你的数据库改:SqlServer/PostgreSQLIsAutoCloseConnection = true,// ===================== 读写分离配置 =====================SlaveConnectionConfigs = new List<SlaveConnectionConfig>(){new SlaveConnectionConfig(){ConnectionString = builder.Configuration.GetConnectionString("SlaveDb"),HitRate = 100 // 权重(多从库可分配比例)}}};return new SqlSugarClient(config);
});// 2. 注册 Redis
builder.Services.AddStackExchangeRedisCache(options =>
{options.Configuration = builder.Configuration.GetConnectionString("Redis");
});builder.Services.AddControllers();
 
 

 

四、读写分离使用规则(自动切换)

 
SqlSugar 完全自动切换主从库,你不用手动控制:
 

自动规则

 
  • 查询(Select) → 自动走 从库
  • 增删改(Insert/Update/Delete) → 自动走 主库
  • 事务内所有操作 → 强制走 主库
 

基础使用示例(Service 层)

 
public class UserService
{private readonly ISqlSugarClient _db;public UserService(ISqlSugarClient db){_db = db;}// ========== 读:自动走从库 ==========public async Task<User> GetUserAsync(int id){return await _db.Queryable<User>().In(id).FirstAsync();}// ========== 写:自动走主库 ==========public async Task<bool> AddUserAsync(User user){return await _db.Insertable(user).ExecuteCommandAsync() > 0;}public async Task<bool> UpdateUserAsync(User user){return await _db.Updateable(user).ExecuteCommandAsync() > 0;}
}
 
 

 

五、Redis 缓存基础使用

 
结合读写分离,实现 “先查缓存 → 缓存没有再查从库 → 存入缓存”
 

1. 封装 Redis 帮助类

 
public class RedisCacheService
{private readonly IDistributedCache _cache;public RedisCacheService(IDistributedCache cache){_cache = cache;}// 获取缓存public async Task<T> GetAsync<T>(string key){var value = await _cache.GetStringAsync(key);return value == null ? default : JsonSerializer.Deserialize<T>(value);}// 设置缓存(带过期时间)public async Task SetAsync<T>(string key, T value, TimeSpan? expiry = null){expiry ??= TimeSpan.FromMinutes(10); // 默认10分钟await _cache.SetStringAsync(key, JsonSerializer.Serialize(value), new DistributedCacheEntryOptions{AbsoluteExpirationRelativeToNow = expiry});}// 删除缓存public async Task RemoveAsync(string key){await _cache.RemoveAsync(key);}
}
 

2. 注册 Redis 帮助类

 
builder.Services.AddScoped<RedisCacheService>();
 
 

 

六、最终:读写分离 + Redis 整合(最佳实践)

 
public class UserService
{private readonly ISqlSugarClient _db;private readonly RedisCacheService _cache;public UserService(ISqlSugarClient db, RedisCacheService cache){_db = db;_cache = cache;}/// <summary>/// 缓存 + 从库查询/// </summary>public async Task<User> GetUserWithCacheAsync(int userId){var cacheKey = $"user:{userId}";// 1. 先查 Redisvar user = await _cache.GetAsync<User>(cacheKey);if (user != null) return user;// 2. Redis 没有 → 查 从库user = await _db.Queryable<User>().In(userId).FirstAsync();if (user == null) return null;// 3. 存入 Redis(10分钟过期)await _cache.SetAsync(cacheKey, user);return user;}/// <summary>/// 更新数据 → 主库 + 删除缓存/// </summary>public async Task<bool> UpdateUserAsync(User user){// 走主库var result = await _db.Updateable(user).ExecuteCommandAsync() > 0;if (result){// 更新成功 → 删除旧缓存await _cache.RemoveAsync($"user:{user.Id}");}return result;}
}
 
 

 

七、强制指定主库 / 从库(特殊场景)

 
如果你需要手动控制:
 
// 强制走主库查询
await _db.Queryable<User>().With(SqlWith.Master).ToListAsync();// 强制走从库
await _db.Queryable<User>().With(SqlWith.Slave).ToListAsync();
http://www.jsqmd.com/news/700216/

相关文章:

  • 生产级AI智能体架构实战:从原型到产品的工程化指南
  • DeepSeek V4写完用哪款降AI?2026年4月4款工具横评 - 我要发一区
  • 2026年独立站+TikTok Shop双轨策略:为什么聪明品牌不再押注单一渠道 - SocialEcho社媒管理
  • OpenCore Legacy Patcher终极指南:如何免费让旧Mac焕发新生
  • 【AI工具】2026年实用免费AI工具全分享:聊天、编程、设计三类工具实测对比
  • 终极DOL汉化美化整合指南:5分钟打造完美中文游戏体验
  • 从“学模型”到“做应用”:AI产品的30天实战进化指南
  • 在 Claude Code 里跑 DeepSeek-V4-Pro,三步搞定
  • 毫米波大规模MIMO中的波束空间处理技术解析
  • 效果展示:LFM2.5-VL-1.6B多语言图片理解实测,小模型也有大能耐
  • C语言内存安全面试必考TOP 15题(2026最新真题库+逐行安全分析)
  • 从‘虹猫蓝兔’到终身学习:聊聊Continual Learning如何让AI模型像人一样成长
  • LSTM时间序列预测实战:从原理到销售预测应用
  • 实用高效的AutoHotkey脚本编译指南:轻松将AHK转换为EXE可执行文件
  • 全局坐标转局部坐标推导 - Ladisson
  • 固态硬盘(SSD)优化特辑:TRIM、预留空间与垃圾回收
  • 深度学习必读三书:从理论到实践的经典指南
  • 工业自动化工程师必装的VSCode插件(2026版协议解析器深度拆解)
  • D2RML终极教程:暗黑2重制版一键多开神器,告别繁琐登录!
  • 用STM32CubeMX和HAL库快速上手MAX30102,告别繁琐的寄存器配置
  • 医疗器械管代的职责
  • AtCoder Beginner Contest 455 ABCDEF 题目解析
  • UniApp跨端视频播放器进阶:从官方限制到自定义全功能实现
  • EB Garamond 12:重塑学术排版的古典字体开源解决方案
  • REBOUND框架:硬件锚定的安全回滚技术解析
  • 嵌入式C语言深度适配轻量大模型(GCC内联汇编级优化+Flash XIP加速+中断上下文LLM推理调度)
  • 全球不到17家团队掌握的VSCode量子配置范式:基于AST动态注入与配置沙箱隔离的工业级实践
  • NumPy数组核心操作与机器学习数据预处理技巧
  • iOS审核被拒?手把手教你搞定Guideline 1.2用户内容安全(附详细承诺信模板)
  • 如何定义强一致和MVCC