SqlSugar 使用教程
SqlSugar 是一款 .NET 生态下开源免费、高性能、低代码、开箱即用的 ORM 框架,MIT 开源协议,性能接近原生 ADO.NET,支持多数据库兼容,是 .NET 开发中最主流的 ORM 之一。
本教程基于 SqlSugar 5.X 最新稳定版编写,覆盖从入门安装到进阶实战的全流程,适配 .NET Core 3.1 / .NET 5+ 及以上版本(.NET Framework 需使用 SqlSugar 非 Core 版本)。
一、环境准备与安装
1. 支持范围
- 框架支持:.NET Core 3.1、.NET 5/6/7/8/9/10、.NET Framework 4.0+
- 数据库支持:SQL Server、MySQL、PostgreSQL、Oracle、SQLite、达梦、人大金仓等主流数据库
- 核心包区分 :
- .NET Core/.NET 5+ :
SqlSugarCore(推荐,持续更新维护) - .NET Framework :
SqlSugar
- .NET Core/.NET 5+ :
2. 安装方式
方式1:NuGet 包管理器(Visual Studio/Rider)
在 NuGet 包管理界面搜索 SqlSugarCore,点击安装对应稳定版即可。
方式2:命令行安装
bash
# .NET CLI 命令(推荐)
dotnet add package SqlSugarCore
# Package Manager 命令
Install-Package SqlSugarCore
二、核心对象初始化
SqlSugar 的所有数据库操作都围绕 SqlSugarClient 核心对象展开,初始化仅需配置 ConnectionConfig 连接配置即可。
1. 基础初始化(控制台/单例场景)
核心配置项说明:
| 配置项 | 作用 | 推荐值 |
|---|---|---|
| ConnectionString | 数据库连接字符串 | 按对应数据库格式填写 |
| DbType | 数据库类型枚举 | 对应数据库类型(如 DbType.MySql) |
| IsAutoCloseConnection | 自动关闭连接 | 必须设为 true,避免连接泄露 |
| InitKeyType | 主键识别方式 | InitKeyType.Attribute(通过特性指定主键,更稳定) |
csharp
using SqlSugar;
// 1. 构建连接配置
var connectionConfig = new ConnectionConfig()
{
ConnectionString = "Server=localhost;Database=TestDB;Uid=root;Pwd=123456;", // MySQL示例
// SQL Server示例:"Server=.;Database=TestDB;Uid=sa;Pwd=123456;TrustServerCertificate=True;"
DbType = DbType.MySql,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute
};
// 2. 创建核心客户端对象
var db = new SqlSugarClient(connectionConfig);
// 3. 可选:配置SQL日志(调试必备,可查看生成的SQL语句)
db.Aop.OnLogExecuting = (sql, pars) =>
{
Console.WriteLine($"【生成SQL】{sql}");
Console.WriteLine($"【参数】{string.Join(",", pars.Select(p => $"{p.ParameterName}={p.Value}"))}");
};
// 4. 测试数据库连接
var isConnected = db.Ado.IsValidConnection();
Console.WriteLine(isConnected ? "数据库连接成功" : "数据库连接失败");
2. 全局单例模式(推荐)
SqlSugarClient 是线程安全的,强烈建议全局单例初始化,避免频繁创建销毁对象带来的性能损耗。
csharp
/// <summary>
/// SqlSugar 单例上下文
/// </summary>
public static class SqlSugarContext
{
// 全局唯一实例
public static readonly SqlSugarClient Db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = "你的数据库连接字符串",
DbType = DbType.MySql,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute
},
// 全局配置AOP
db =>
{
// 全局SQL日志
db.Aop.OnLogExecuting = (sql, pars) =>
{
Console.WriteLine($"SQL:{sql}\r\n参数:{string.Join(",", pars.Select(p => $"{p.ParameterName}={p.Value}"))}");
};
});
}
// 使用方式
var list = SqlSugarContext.Db.Queryable<User>().ToList();
3. ASP.NET Core 依赖注入(Web项目推荐)
在 Program.cs 中注入服务,支持 Scope/单例 两种生命周期:
csharp
var builder = WebApplication.CreateBuilder(args);
// 读取配置文件中的连接字符串
var connectionString = builder.Configuration.GetConnectionString("Default");
// 注入SqlSugar客户端(Scope模式,推荐Web项目使用)
builder.Services.AddScoped<ISqlSugarClient>(sp =>
{
return new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = connectionString,
DbType = DbType.MySql,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute
});
});
// 单例模式注入
// builder.Services.AddSingleton<ISqlSugarClient>(...);
var app = builder.Build();
app.Run();
配置文件 appsettings.json 中添加连接字符串:
json
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=TestDB;Uid=root;Pwd=123456;"
}
}
三、实体映射与表结构管理
SqlSugar 支持 CodeFirst(代码优先,实体生成表) 和 DbFirst(数据库优先,表生成实体) 两种模式,通过特性完成实体与表/字段的精准映射。
1. 实体映射特性详解
核心特性分为类级别的 SugarTable 和属性级别的 SugarColumn,常用参数如下:
csharp
using SqlSugar;
/// <summary>
/// 用户实体类 示例
/// </summary>
[SugarTable("sys_user")] // 指定数据库表名,不填则默认使用类名作为表名
public class User
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnName = "user_id")]
// 主键、自增、映射数据库字段名user_id
public int UserId { get; set; }
[SugarColumn(ColumnName = "user_name", Length = 50, IsNullable = false)]
// 字段名映射、长度50、非空
public string UserName { get; set; }
[SugarColumn(ColumnName = "user_age", DefaultValue = "18")]
// 默认值18
public int Age { get; set; }
[SugarColumn(ColumnName = "create_time", DefaultValue = "NOW()", IsOnlyIgnoreInsert = true)]
// 默认值为当前时间,插入时忽略该字段(由数据库生成)
public DateTime CreateTime { get; set; }
[SugarColumn(IsIgnore = true)]
// 忽略该字段,不映射到数据库表
public string TempData { get; set; }
[SugarColumn(IsNullable = true, Length = 100)]
public string Email { get; set; }
}
2. CodeFirst 代码优先(实体生成表)
无需手动写建表SQL,通过实体类自动生成/同步数据库表结构,适合新项目开发。
csharp
// 1. 单个实体生成表(表不存在则创建,存在则同步字段变更)
SqlSugarContext.Db.CodeFirst.InitTables<User>();
// 2. 批量多个实体生成表
SqlSugarContext.Db.CodeFirst.InitTables(typeof(User), typeof(Order), typeof(OrderItem));
// 3. 高级配置:自定义表结构
SqlSugarContext.Db.CodeFirst
.ConfigTable<User>(t => t.TableName = "sys_user") // 自定义表名
.ConfigColumn<User>(c =>
{
if (c.PropertyName == nameof(User.UserName))
{
c.Length = 100; // 自定义字段长度
c.IsNullable = false; // 非空
}
})
.InitTables<User>();
3. DbFirst 数据库优先(表生成实体)
已有数据库表时,一键生成对应的实体类,无需手动编写。
csharp
// 1. 生成所有表的实体类到指定路径
SqlSugarContext.Db.DbFirst
.CreateClassFile(@"D:\Project\Models\", "YourProject.Models"); // 路径、命名空间
// 2. 生成指定表的实体类
SqlSugarContext.Db.DbFirst
.Where("sys_user,sys_order") // 指定表名,多个用逗号分隔
.CreateClassFile(@"D:\Project\Models\", "YourProject.Models");
// 3. 生成时添加默认特性
SqlSugarContext.Db.DbFirst
.IsCreateAttribute() // 自动生成SugarTable/SugarColumn特性
.CreateClassFile(@"D:\Project\Models\", "YourProject.Models");
四、核心 CRUD 操作
SqlSugar 采用链式API设计,语法简洁直观,支持同步+异步双模式(Web项目推荐优先使用异步方法),覆盖99%的业务场景。
以下示例均使用 SqlSugarContext.Db 单例对象,实体以 User 为例。
1. 新增操作(Insert)
csharp
#region 同步方法
// 1. 单条新增
var user = new User() { UserName = "张三", Age = 20, Email = "zhangsan@test.com" };
int rows = SqlSugarContext.Db.Insertable(user).ExecuteCommand(); // 返回受影响行数
// 2. 单条新增并返回自增主键ID(自增主键专用)
int newUserId = SqlSugarContext.Db.Insertable(user).ExecuteReturnIdentity();
// 3. 批量新增(性能远高于循环单条插入)
var userList = new List<User>()
{
new User(){ UserName = "李四", Age = 22, Email = "lisi@test.com" },
new User(){ UserName = "王五", Age = 25, Email = "wangwu@test.com" }
};
int batchRows = SqlSugarContext.Db.Insertable(userList).ExecuteCommand();
// 4. 大数据批量插入(10万+数据,BulkCopy模式,性能拉满)
SqlSugarContext.Db.Fastest<User>().BulkCopy(userList);
// 5. 忽略指定字段插入
SqlSugarContext.Db.Insertable(user)
.IgnoreColumns(u => u.CreateTime) // 忽略CreateTime字段
.ExecuteCommand();
// 6. 仅插入指定字段
SqlSugarContext.Db.Insertable(user)
.InsertColumns(u => new { u.UserName, u.Age }) // 仅插入UserName和Age
.ExecuteCommand();
#endregion
#region 异步方法(推荐)
// 常用异步示例
int asyncRows = await SqlSugarContext.Db.Insertable(user).ExecuteCommandAsync();
int asyncNewId = await SqlSugarContext.Db.Insertable(user).ExecuteReturnIdentityAsync();
int asyncBatchRows = await SqlSugarContext.Db.Insertable(userList).ExecuteCommandAsync();
#endregion
2. 查询操作(Query)
查询是业务中最常用的操作,SqlSugar 提供 Queryable 链式查询对象,支持复杂条件、聚合、排序等操作。
csharp
#region 基础查询
// 1. 查询表所有数据
var allUser = SqlSugarContext.Db.Queryable<User>().ToList();
// 2. 按主键查询单条数据
var userById = SqlSugarContext.Db.Queryable<User>().InSingle(1); // 主键=1
// 3. 条件查询列表
var userByWhere = SqlSugarContext.Db.Queryable<User>()
.Where(u => u.Age > 18 && u.UserName.Contains("张")) // 年龄>18 且 用户名包含"张"
.ToList();
// 4. 单条条件查询(无数据返回null)
var userFirst = SqlSugarContext.Db.Queryable<User>()
.Where(u => u.UserName == "张三")
.First();
// 5. 查询指定字段(避免select *)
var userSelect = SqlSugarContext.Db.Queryable<User>()
.Select(u => new { u.UserId, u.UserName, u.Age }) // 匿名对象
.ToList();
// 6. 排序查询
var userOrder = SqlSugarContext.Db.Queryable<User>()
.OrderBy(u => u.CreateTime, OrderByType.Desc) // 按创建时间倒序
.OrderBy(u => u.Age, OrderByType.Asc) // 再按年龄正序
.ToList();
// 7. 分页查询(业务高频使用)
int pageIndex = 1; // 页码
int pageSize = 10; // 每页条数
int totalCount = 0; // 总条数
var pageList = SqlSugarContext.Db.Queryable<User>()
.Where(u => u.Age > 18)
.ToPageList(pageIndex, pageSize, ref totalCount);
Console.WriteLine($"总条数:{totalCount},总页数:{Math.Ceiling((double)totalCount / pageSize)}");
#endregion
#region 聚合查询
// 统计总数
int count = SqlSugarContext.Db.Queryable<User>().Count(u => u.Age > 18);
// 最大值
int maxAge = SqlSugarContext.Db.Queryable<User>().Max(u => u.Age);
// 最小值
int minAge = SqlSugarContext.Db.Queryable<User>().Min(u => u.Age);
// 平均值
double avgAge = SqlSugarContext.Db.Queryable<User>().Avg(u => u.Age);
// 求和
int sumAge = SqlSugarContext.Db.Queryable<User>().Sum(u => u.Age);
// 判断是否存在
bool isExist = SqlSugarContext.Db.Queryable<User>().Any(u => u.UserName == "张三");
#endregion
#region 异步方法
var allUserAsync = await SqlSugarContext.Db.Queryable<User>().ToListAsync();
var countAsync = await SqlSugarContext.Db.Queryable<User>().CountAsync();
var pageListAsync = await SqlSugarContext.Db.Queryable<User>().ToPageListAsync(pageIndex, pageSize, totalCount);
#endregion
3. 更新操作(Update)
csharp
#region 同步方法
// 1. 全实体更新(根据主键更新,推荐先查询再更新)
var updateUser = SqlSugarContext.Db.Queryable<User>().InSingle(1);
updateUser.UserName = "张三修改";
updateUser.Age = 30;
int updateRows = SqlSugarContext.Db.Updateable(updateUser).ExecuteCommand();
// 2. 仅更新指定字段(推荐,避免全字段更新)
SqlSugarContext.Db.Updateable<User>()
.SetColumns(u => u.UserName == "张三修改")
.SetColumns(u => u.Age == 30)
.Where(u => u.UserId == 1)
.ExecuteCommand();
// 3. 实体指定字段更新
SqlSugarContext.Db.Updateable(updateUser)
.UpdateColumns(u => new { u.UserName, u.Age }) // 仅更新这两个字段
.ExecuteCommand();
// 4. 条件批量更新(年龄<18的用户,年龄+1)
SqlSugarContext.Db.Updateable<User>()
.SetColumns(u => new User() { Age = u.Age + 1 })
.Where(u => u.Age < 18)
.ExecuteCommand();
// 5. 批量更新
var updateList = new List<User>()
{
new User(){ UserId = 1, UserName = "张三", Age = 20 },
new User(){ UserId = 2, UserName = "李四", Age = 21 }
};
SqlSugarContext.Db.Updateable(updateList).ExecuteCommand();
// 6. 忽略指定字段更新
SqlSugarContext.Db.Updateable(updateUser)
.IgnoreColumns(u => u.CreateTime) // 忽略CreateTime字段不更新
.ExecuteCommand();
#endregion
#region 异步方法
int asyncUpdateRows = await SqlSugarContext.Db.Updateable(updateUser).ExecuteCommandAsync();
#endregion
4. 删除操作(Delete)
注意:物理删除需谨慎,生产环境推荐使用软删除(逻辑删除),通过更新字段标记删除状态。
csharp
#region 同步方法
// 1. 按主键删除
int deleteRows = SqlSugarContext.Db.Deleteable<User>().In(1).ExecuteCommand();
// 2. 批量主键删除
SqlSugarContext.Db.Deleteable<User>().In(new int[] { 1, 2, 3 }).ExecuteCommand();
// 3. 条件删除
SqlSugarContext.Db.Deleteable<User>()
.Where(u => u.Age < 18)
.ExecuteCommand();
// 4. 实体删除(根据主键)
var deleteUser = SqlSugarContext.Db.Queryable<User>().InSingle(1);
SqlSugarContext.Db.Deleteable(deleteUser).ExecuteCommand();
#endregion
#region 异步方法
int asyncDeleteRows = await SqlSugarContext.Db.Deleteable<User>().In(1).ExecuteCommandAsync();
#endregion
五、进阶实战用法
1. 多表联查
SqlSugar 提供极简的联表语法,支持 LeftJoin、InnerJoin、RightJoin,最多支持16表联查。
csharp
// 示例:订单表 左联 用户表 左联 订单明细表
// 定义关联实体
[SugarTable("sys_order")]
public class Order
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int OrderId { get; set; }
public int UserId { get; set; }
public string OrderNo { get; set; }
public decimal TotalAmount { get; set; }
public DateTime CreateTime { get; set; }
}
[SugarTable("sys_order_item")]
public class OrderItem
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int ItemId { get; set; }
public int OrderId { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
}
// 2表联查:查询订单及对应用户信息
var orderList = SqlSugarContext.Db.Queryable<Order>()
.LeftJoin<User>((o, u) => o.UserId == u.UserId) // 订单表左联用户表,关联条件
.Where((o, u) => o.TotalAmount > 100)
.Select((o, u) => new
{
o.OrderId,
o.OrderNo,
o.TotalAmount,
u.UserId,
u.UserName
})
.ToList();
// 3表联查:查询订单、用户、订单明细
var orderDetailList = SqlSugarContext.Db.Queryable<Order>()
.LeftJoin<User>((o, u) => o.UserId == u.UserId)
.LeftJoin<OrderItem>((o, u, i) => o.OrderId == i.OrderId)
.Where((o, u, i) => o.OrderId == 1)
.Select((o, u, i) => new
{
o.OrderId,
o.OrderNo,
u.UserName,
i.ProductName,
i.Quantity,
i.Price
})
.ToList();
2. 事务处理
SqlSugar 支持多种事务模式,保证数据操作的原子性,异常时自动回滚。
csharp
#region 方式1:使用Using事务块(推荐)
try
{
// 开启事务
using (var tran = SqlSugarContext.Db.CreateTran())
{
// 事务内的多个操作
var user = new User() { UserName = "事务测试", Age = 20 };
int userId = SqlSugarContext.Db.Insertable(user).ExecuteReturnIdentity();
var order = new Order() { UserId = userId, OrderNo = "ORD2024001", TotalAmount = 100 };
SqlSugarContext.Db.Insertable(order).ExecuteCommand();
// 提交事务
tran.Commit();
Console.WriteLine("事务执行成功");
}
}
catch (Exception ex)
{
// 异常自动回滚,无需手动处理
Console.WriteLine($"事务执行失败,已回滚:{ex.Message}");
}
#region 方式2:手动开启/提交/回滚事务
try
{
SqlSugarContext.Db.Ado.BeginTran(); // 开启事务
// 业务操作
SqlSugarContext.Db.Insertable(new User() { UserName = "手动事务测试" }).ExecuteCommand();
SqlSugarContext.Db.Ado.CommitTran(); // 提交事务
}
catch (Exception ex)
{
SqlSugarContext.Db.Ado.RollbackTran(); // 回滚事务
Console.WriteLine($"事务执行失败,已回滚:{ex.Message}");
}
#endregion
3. 原生SQL执行
对于复杂统计、存储过程调用等场景,SqlSugar 支持直接执行原生SQL语句,兼顾灵活性与安全性。
csharp
#region 查询类SQL
// 1. 原生SQL查询列表
var userList = SqlSugarContext.Db.Ado.SqlQuery<User>("select * from sys_user where age > @Age",
new { Age = 18 }); // 参数化查询,避免SQL注入
// 2. 原生SQL查询单值
int count = SqlSugarContext.Db.Ado.SqlQuerySingle<int>("select count(1) from sys_user where age > @Age",
new { Age = 18 });
// 3. 匿名对象查询
var list = SqlSugarContext.Db.Ado.SqlQueryDynamic("select user_id,user_name from sys_user where age > @Age",
new { Age = 18 });
#endregion
#region 增删改类SQL
// 执行非查询SQL,返回受影响行数
int rows = SqlSugarContext.Db.Ado.ExecuteCommand(
"update sys_user set age = age + 1 where user_id = @UserId",
new { UserId = 1 });
#endregion
#region 存储过程调用
SqlSugarContext.Db.Ado.UseStoredProcedure().ExecuteCommand("Proc_UpdateUserAge",
new { UserId = 1, AddAge = 1 });
#endregion
4. 全局过滤(软删除/租户隔离)
通过全局过滤器,自动为所有查询追加条件,无需手动在每个查询中写Where,适合软删除、多租户隔离等场景。
csharp
// 1. 给实体添加软删除字段
[SugarTable("sys_user")]
public class User
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int UserId { get; set; }
public string UserName { get; set; }
public int Age { get; set; }
[SugarColumn(DefaultValue = "0")]
public bool IsDeleted { get; set; } // 软删除标记:0=未删除,1=已删除
}
// 2. 初始化SqlSugarClient时配置全局过滤器
var db = new SqlSugarClient(new ConnectionConfig()
{
// 连接配置...
},
db =>
{
// 全局软删除过滤器:所有查询自动追加 IsDeleted=false
db.QueryFilter.AddTableFilter<User>(u => u.IsDeleted == false);
// 多租户过滤器示例
// db.QueryFilter.AddTableFilter<User>(u => u.TenantId == 当前租户ID);
});
// 3. 使用:查询时自动过滤已删除数据,无需手动写Where
var list = db.Queryable<User>().ToList();
// 生成的SQL自动追加 where IsDeleted=0
// 4. 临时禁用过滤器(查询已删除数据)
var allList = db.Queryable<User>().Filter(null, false).ToList();
六、最佳实践与官方资源
1. 开发最佳实践
- 单例模式优先 :控制台/WinForm/WPF 项目使用全局单例,Web 项目使用依赖注入,避免频繁创建
SqlSugarClient实例。 - 自动释放连接 :必须开启
IsAutoCloseConnection=true,杜绝连接泄露问题。 - 异步优先 :Web 项目优先使用
Async结尾的异步方法,提升服务并发能力。 - 参数化查询:原生SQL必须使用参数化,禁止字符串拼接SQL,避免SQL注入风险。
- 避免select *:查询时指定需要的字段,减少数据传输,提升性能。
- 批量操作:大量数据新增/更新时,使用批量API而非循环单条操作,性能差距可达百倍。
- 调试必开日志 :开发环境开启
OnLogExecuting日志,查看生成的SQL,及时发现性能问题。
2. 官方核心资源
- 官方文档:www.donet5.com/Home/Doc (最全中文文档,持续更新)
- GitHub 仓库:github.com/DotNetNext/... (源码、Issue、更新日志)
- 官方视频教程:B站搜索 SqlSugar 官方教程,有完整的入门到进阶视频
3. 常见问题排查
- 连接失败:检查连接字符串格式、数据库服务是否启动、网络是否通畅、账号密码是否正确。
- 主键自增不生效 :检查实体是否配置
IsPrimaryKey=true和IsIdentity=true,数据库表字段是否设置自增。 - 字段映射失败 :检查
SugarColumn的ColumnName是否正确,是否开启了IsIgnore=true。 - SQL生成异常:开启SQL日志,查看生成的SQL语句,排查表达式是否支持转换为SQL。
- 内存溢出/连接泄露 :确认开启了
IsAutoCloseConnection=true,未频繁创建SqlSugarClient实例。