SqlSugar 使用教程

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

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. 开发最佳实践

  1. 单例模式优先 :控制台/WinForm/WPF 项目使用全局单例,Web 项目使用依赖注入,避免频繁创建 SqlSugarClient 实例。
  2. 自动释放连接 :必须开启 IsAutoCloseConnection=true,杜绝连接泄露问题。
  3. 异步优先 :Web 项目优先使用 Async 结尾的异步方法,提升服务并发能力。
  4. 参数化查询:原生SQL必须使用参数化,禁止字符串拼接SQL,避免SQL注入风险。
  5. 避免select *:查询时指定需要的字段,减少数据传输,提升性能。
  6. 批量操作:大量数据新增/更新时,使用批量API而非循环单条操作,性能差距可达百倍。
  7. 调试必开日志 :开发环境开启 OnLogExecuting 日志,查看生成的SQL,及时发现性能问题。

2. 官方核心资源

  • 官方文档:www.donet5.com/Home/Doc (最全中文文档,持续更新)
  • GitHub 仓库:github.com/DotNetNext/... (源码、Issue、更新日志)
  • 官方视频教程:B站搜索 SqlSugar 官方教程,有完整的入门到进阶视频

3. 常见问题排查

  1. 连接失败:检查连接字符串格式、数据库服务是否启动、网络是否通畅、账号密码是否正确。
  2. 主键自增不生效 :检查实体是否配置 IsPrimaryKey=trueIsIdentity=true,数据库表字段是否设置自增。
  3. 字段映射失败 :检查 SugarColumnColumnName 是否正确,是否开启了 IsIgnore=true
  4. SQL生成异常:开启SQL日志,查看生成的SQL语句,排查表达式是否支持转换为SQL。
  5. 内存溢出/连接泄露 :确认开启了 IsAutoCloseConnection=true,未频繁创建 SqlSugarClient 实例。
相关推荐
Oneslide2 小时前
Docker Compose 重启 RabbitMQ 数据丢失?
后端
架构师沉默2 小时前
为什么国外程序员都写独立博客,而国内都在公众号?
java·后端·架构
开心就好20252 小时前
Win11 抓包工具怎么选?网页请求与设备流量抓取
后端·ios
GIS阵地2 小时前
QgsProviderMetadata 详解(基于 QGIS 3.40.13 API)
数据库·qt·arcgis·oracle·gis·开源软件·qgis
qq_366086222 小时前
sql server OUTER APPLY使用
数据库·sql·mysql
Sunshine for you2 小时前
使用Flask快速搭建轻量级Web应用
jvm·数据库·python
爱丽_2 小时前
Spring 事务:传播行为、失效场景、回滚规则与最佳实践
java·后端·spring
qwehjk20082 小时前
如何从Python初学者进阶为专家?
jvm·数据库·python
zzh0812 小时前
Mysql数据库备份与恢复笔记
数据库·笔记·mysql