> 技术文档 > SqlSugar ORM框架详解_sqlsuger

SqlSugar ORM框架详解_sqlsuger


目录

  • 简介
  • 特性与优势
  • 安装与配置
  • 基础使用
  • 实体映射
  • 数据库操作
  • 查询操作
  • 高级功能
  • 性能优化
  • 最佳实践
  • 总结

简介

SqlSugar是一个轻量级、高性能的.NET ORM框架,由中国开发者维护,专为简化数据库操作而设计。它支持多种数据库,提供了丰富的功能和优秀的性能表现,是.NET开发中非常受欢迎的ORM选择。

为什么选择SqlSugar?

  • 轻量级:框架体积小,启动快速
  • 高性能:优化的SQL生成和执行机制
  • 易用性:简洁的API设计,学习成本低
  • 多数据库支持:支持主流数据库系统
  • 中文文档:完善的中文文档和社区支持

特性与优势

核心特性

  1. 多数据库支持

    • SQL Server
    • MySQL
    • PostgreSQL
    • Oracle
    • SQLite
    • 达梦数据库
    • 人大金仓等国产数据库
  2. 丰富的查询方式

    • Lambda表达式查询
    • SQL语句查询
    • 存储过程调用
    • 动态查询构建
  3. 代码生成功能

    • 根据数据库表生成实体类
    • 自动生成仓储层代码
    • 支持模板自定义
  4. 事务管理

    • 自动事务管理
    • 手动事务控制
    • 分布式事务支持

性能优势

// 高性能的批量操作var users = new List<User>();for (int i = 0; i < 10000; i++){ users.Add(new User { Name = $\"User{i}\", Age = 20 + i % 50 });}// 批量插入,性能优异db.Insertable(users).ExecuteCommand();

安装与配置

NuGet包安装

# 核心包Install-Package SqlSugar# 特定数据库扩展Install-Package SqlSugar.SqlServerInstall-Package SqlSugar.MySqlInstall-Package SqlSugar.PostgreSQL

基础配置

using SqlSugar;// 数据库连接配置var db = new SqlSugarClient(new ConnectionConfig(){ ConnectionString = \"Server=.;Database=TestDB;Trusted_Connection=true;\", DbType = DbType.SqlServer, IsAutoCloseConnection = true, // 自动关闭连接 InitKeyType = InitKeyType.Attribute // 使用特性初始化});// 日志配置db.Aop.OnLogExecuting = (sql, pars) =>{ Console.WriteLine($\"SQL: {sql}\"); Console.WriteLine($\"Parameters: {string.Join(\",\", pars?.Select(p => $\"{p.ParameterName}:{p.Value}\"))}\");};

多数据库配置

var configs = new List<ConnectionConfig>{ new ConnectionConfig { ConfigId = \"db1\", ConnectionString = \"SqlServer连接字符串\", DbType = DbType.SqlServer, IsAutoCloseConnection = true }, new ConnectionConfig { ConfigId = \"db2\", ConnectionString = \"MySQL连接字符串\", DbType = DbType.MySql, IsAutoCloseConnection = true }};var db = new SqlSugarScope(configs);// 切换数据库var sqlServerDb = db.GetConnection(\"db1\");var mysqlDb = db.GetConnection(\"db2\");

基础使用

实体类定义

[SugarTable(\"Users\")]public class User{ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id { get; set; } [SugarColumn(Length = 50, IsNullable = false)] public string Name { get; set; } [SugarColumn(IsNullable = true)] public int? Age { get; set; } [SugarColumn(IsNullable = true)] public DateTime? CreateTime { get; set; } [SugarColumn(IsIgnore = true)] // 忽略该字段 public string TempProperty { get; set; }}

基本CRUD操作

// 插入var user = new User { Name = \"张三\", Age = 25, CreateTime = DateTime.Now };var id = db.Insertable(user).ExecuteReturnIdentity();// 查询var users = db.Queryable<User>().ToList();var user = db.Queryable<User>().Where(u => u.Id == 1).First();// 更新db.Updateable<User>() .SetColumns(u => new User { Age = 26 }) .Where(u => u.Id == 1) .ExecuteCommand();// 删除db.Deleteable<User>().Where(u => u.Id == 1).ExecuteCommand();

实体映射

特性配置

[SugarTable(\"tb_product\")]public class Product{ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int ProductId { get; set; } [SugarColumn(ColumnName = \"product_name\", Length = 100)] public string Name { get; set; } [SugarColumn(ColumnName = \"unit_price\", DecimalDigits = 2)] public decimal Price { get; set; } [SugarColumn(ColumnName = \"create_date\", IsNullable = true)] public DateTime? CreateDate { get; set; } [SugarColumn(IsJson = true)] // JSON字段映射 public List<string> Tags { get; set; }}

Fluent API配置

db.CodeFirst.ConfigQuery<User>() .HasKey(u => u.Id) .HasIndex(u => u.Name, true) // 唯一索引 .HasColumn(u => u.Name, col => col.IsNullable(false).HasMaxLength(50)) .HasColumn(u => u.Age, col => col.IsNullable(true));

枚举映射

public enum UserStatus{ Active = 1, Inactive = 0, Deleted = -1}public class User{ public int Id { get; set; } public string Name { get; set; } [SugarColumn(IsEnableUpdateVersionValidation = true)] public UserStatus Status { get; set; }}

数据库操作

数据库初始化

// 创建数据库db.DbMaintenance.CreateDatabase();// 根据实体创建表db.CodeFirst.InitTables<User, Product, Order>();// 检查表是否存在if (!db.DbMaintenance.IsAnyTable(\"Users\")){ db.CodeFirst.InitTables<User>();}

表结构管理

// 添加列db.DbMaintenance.AddColumn(\"Users\", new DbColumnInfo{ DbColumnName = \"Email\", DataType = \"varchar\", Length = 100, IsNullable = true});// 删除列db.DbMaintenance.DropColumn(\"Users\", \"TempColumn\");// 重命名表db.DbMaintenance.RenameTable(\"OldTableName\", \"NewTableName\");

索引管理

// 创建索引db.DbMaintenance.AddIndex(\"Users\", new string[] { \"Name\", \"Age\" });// 删除索引db.DbMaintenance.DropIndex(\"Users\", \"IX_Users_Name_Age\");// 获取索引信息var indexes = db.DbMaintenance.GetIndexList(\"Users\");

查询操作

Lambda表达式查询

// 基础查询var users = db.Queryable<User>()  .Where(u => u.Age > 18)  .OrderBy(u => u.CreateTime)  .ToList();// 复杂条件查询var result = db.Queryable<User>()  .Where(u => u.Name.Contains(\"张\") && u.Age.HasValue)  .WhereIF(!string.IsNullOrEmpty(searchName), u => u.Name == searchName)  .Select(u => new  {  u.Id,  u.Name,  Age = u.Age ?? 0,  AgeGroup = u.Age > 30 ? \"成年\" : \"青年\"  })  .ToList();

分页查询

// 方式一:使用ToPageListint pageIndex = 1, pageSize = 10;var pageResult = db.Queryable<User>()  .Where(u => u.Age > 18)  .OrderBy(u => u.Id)  .ToPageList(pageIndex, pageSize);Console.WriteLine($\"总记录数: {pageResult.TotalCount}\");Console.WriteLine($\"总页数: {pageResult.TotalPages}\");// 方式二:使用ToOffsetPagevar offsetResult = db.Queryable<User>()  .Where(u => u.Age > 18)  .OrderBy(u => u.Id)  .ToOffsetPage(pageIndex, pageSize);

联表查询

// 内连接var result = db.Queryable<User, Order>((u, o) => new JoinQueryInfos( JoinType.Inner, u.Id == o.UserId))  .Select((u, o) => new  {  UserName = u.Name,  OrderId = o.Id,  OrderAmount = o.Amount  })  .ToList();// 左连接var leftJoinResult = db.Queryable<User>() .LeftJoin<Order>((u, o) => u.Id == o.UserId) .Select((u, o) => new { u.Name, OrderCount = SqlFunc.IsNull(o.Id, 0) }) .ToList();

子查询

// 子查询示例var subQuery = db.Queryable<Order>()  .Where(o => o.Status == OrderStatus.Completed)  .GroupBy(o => o.UserId)  .Select(o => new { UserId = o.UserId, TotalAmount = SqlFunc.Sum(o.Amount) });var result = db.Queryable<User>()  .Where(u => SqlFunc.Subqueryable(subQuery) .Where(s => s.UserId == u.Id && s.TotalAmount > 1000) .Any())  .ToList();

聚合查询

// 分组聚合var groupResult = db.Queryable<Order>()  .GroupBy(o => new { o.UserId, o.Status })  .Select(o => new  { o.UserId, o.Status, Count = SqlFunc.Count(o.Id), TotalAmount = SqlFunc.Sum(o.Amount), AvgAmount = SqlFunc.Avg(o.Amount), MaxAmount = SqlFunc.Max(o.Amount), MinAmount = SqlFunc.Min(o.Amount)  })  .ToList();// Having子句var havingResult = db.Queryable<Order>()  .GroupBy(o => o.UserId)  .Having(o => SqlFunc.Sum(o.Amount) > 5000)  .Select(o => new  { UserId = o.UserId, TotalAmount = SqlFunc.Sum(o.Amount)  })  .ToList();

高级功能

事务管理

// 自动事务try{ db.BeginTran(); // 执行多个操作 db.Insertable(user).ExecuteCommand(); db.Updateable(order).ExecuteCommand(); db.Deleteable<Product>().Where(p => p.Id == 1).ExecuteCommand(); db.CommitTran();}catch (Exception ex){ db.RollbackTran(); throw;}// 使用using语句using (var tran = db.UseTran()){ db.Insertable(user).ExecuteCommand(); db.Updateable(order).ExecuteCommand(); tran.Complete(); // 提交事务}

批量操作

// 批量插入var users = new List<User>();for (int i = 0; i < 10000; i++){ users.Add(new User { Name = $\"User{i}\", Age = 20 + i % 50 });}// 高性能批量插入db.Fastest<User>().BulkCopy(users);// 批量更新var updateUsers = db.Queryable<User>().Where(u => u.Age < 25).ToList();updateUsers.ForEach(u => u.Age += 1);db.Fastest<User>().BulkUpdate(updateUsers);// 批量删除db.Deleteable<User>().Where(u => u.Age > 60).ExecuteCommand();

缓存功能

// 查询缓存var cachedUsers = db.Queryable<User>()  .Where(u => u.Status == UserStatus.Active)  .WithCache(60) // 缓存60秒  .ToList();// 自定义缓存键var customCachedUsers = db.Queryable<User>() .Where(u => u.Age > 18) .WithCache(\"active_users\", 300) // 自定义缓存键,缓存5分钟 .ToList();// 清除缓存db.RemoveDataCache(\"active_users\");

读写分离

var configs = new List<ConnectionConfig>{ new ConnectionConfig { ConfigId = \"master\", ConnectionString = \"主库连接字符串\", DbType = DbType.SqlServer, IsAutoCloseConnection = true }, new ConnectionConfig { ConfigId = \"slave1\", ConnectionString = \"从库1连接字符串\", DbType = DbType.SqlServer, IsAutoCloseConnection = true, SlaveConnectionConfigs = new List<SlaveConnectionConfig> { new SlaveConnectionConfig { HitRate = 50 }, // 50%命中率 } }};var db = new SqlSugarScope(configs);// 查询自动使用从库var users = db.Queryable<User>().ToList();// 强制使用主库查询var masterUsers = db.GetConnection(\"master\").Queryable<User>().ToList();

多租户支持

// 配置多租户db.SetTenantTable(\"tenant1\", \"Users_Tenant1\");db.SetTenantTable(\"tenant2\", \"Users_Tenant2\");// 切换租户db.ChangeTenant(\"tenant1\");var tenant1Users = db.Queryable<User>().ToList(); // 查询Users_Tenant1表db.ChangeTenant(\"tenant2\");var tenant2Users = db.Queryable<User>().ToList(); // 查询Users_Tenant2表

性能优化

查询优化

// 1. 使用异步操作var usersAsync = await db.Queryable<User>() .Where(u => u.Age > 18) .ToListAsync();// 2. 只查询需要的字段var userNames = db.Queryable<User>()  .Select(u => u.Name)  .ToList();// 3. 使用NoLock(SQL Server)var noLockUsers = db.Queryable<User>()  .With(SqlWith.NoLock)  .ToList();// 4. 分页查询大数据量var largeDataPage = db.Queryable<User>().OrderBy(u => u.Id).ToOffsetPage(1, 1000);

连接池优化

var config = new ConnectionConfig{ ConnectionString = \"连接字符串\", DbType = DbType.SqlServer, IsAutoCloseConnection = true, // 连接池配置 ConfigureExternalServices = new ConfigureExternalServices { DataInfoCacheService = new HttpRuntimeCache(), // 使用缓存 SqlFuncServices = new List<SqlFuncExternal>() // 自定义SQL函数 }, // 性能配置 MoreSettings = new ConnMoreSettings { IsAutoRemoveDataCache = true, // 自动清理缓存 IsWithNoLockQuery = true, // 默认使用NoLock DefaultCacheDurationInSeconds = 600 // 默认缓存时间 }};

SQL优化建议

// 1. 避免N+1查询问题var usersWithOrders = db.Queryable<User>() .Includes(u => u.Orders) // 一次性加载关联数据 .ToList();// 2. 使用批量操作代替循环// 错误方式foreach (var user in users){ db.Updateable(user).ExecuteCommand(); // N次数据库访问}// 正确方式db.Updateable(users).ExecuteCommand(); // 1次数据库访问// 3. 合理使用索引var indexedQuery = db.Queryable<User>()  .Where(u => u.Email == \"test@example.com\") // 确保Email字段有索引  .First();

最佳实践

1. 仓储模式实现

public interface IRepository<T> where T : class, new(){ Task<T> GetByIdAsync(object id); Task<List<T>> GetAllAsync(); Task<bool> InsertAsync(T entity); Task<bool> UpdateAsync(T entity); Task<bool> DeleteAsync(object id);}public class Repository<T> : IRepository<T> where T : class, new(){ private readonly ISqlSugarClient _db; public Repository(ISqlSugarClient db) { _db = db; } public async Task<T> GetByIdAsync(object id) { return await _db.Queryable<T>().InSingleAsync(id); } public async Task<List<T>> GetAllAsync() { return await _db.Queryable<T>().ToListAsync(); } public async Task<bool> InsertAsync(T entity) { return await _db.Insertable(entity).ExecuteCommandAsync() > 0; } public async Task<bool> UpdateAsync(T entity) { return await _db.Updateable(entity).ExecuteCommandAsync() > 0; } public async Task<bool> DeleteAsync(object id) { return await _db.Deleteable<T>().In(id).ExecuteCommandAsync() > 0; }}

2. 依赖注入配置

// Startup.cs 或 Program.csservices.AddSingleton<ISqlSugarClient>(provider =>{ var config = new ConnectionConfig { ConnectionString = Configuration.GetConnectionString(\"DefaultConnection\"), DbType = DbType.SqlServer, IsAutoCloseConnection = true, InitKeyType = InitKeyType.Attribute }; var db = new SqlSugarClient(config); // 配置日志 db.Aop.OnLogExecuting = (sql, pars) => { var logger = provider.GetService<ILogger<SqlSugarClient>>(); logger.LogInformation($\"SQL: {sql}\"); }; return db;});services.AddScoped(typeof(IRepository<>), typeof(Repository<>));

3. 配置管理

public class DatabaseOptions{ public string ConnectionString { get; set; } public string DbType { get; set; } public bool EnableLogging { get; set; } public int CommandTimeout { get; set; } = 30;}// appsettings.json{ \"Database\": { \"ConnectionString\": \"Server=.;Database=TestDB;Trusted_Connection=true;\", \"DbType\": \"SqlServer\", \"EnableLogging\": true, \"CommandTimeout\": 60 }}// 配置使用services.Configure<DatabaseOptions>(Configuration.GetSection(\"Database\"));

4. 异常处理

public class DatabaseExceptionHandler{ private readonly ILogger<DatabaseExceptionHandler> _logger; public DatabaseExceptionHandler(ILogger<DatabaseExceptionHandler> logger) { _logger = logger; } public async Task<T> ExecuteWithRetryAsync<T>(Func<Task<T>> operation, int maxRetries = 3) { for (int i = 0; i < maxRetries; i++) { try { return await operation(); } catch (Exception ex) when (i < maxRetries - 1) { _logger.LogWarning($\"数据库操作失败,正在重试... 第{i + 1}次,异常: {ex.Message}\"); await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, i))); // 指数退避 } } return await operation(); // 最后一次尝试,如果失败则抛出异常 }}

5. 单元测试

[TestClass]public class UserRepositoryTests{ private ISqlSugarClient _db; private IRepository<User> _userRepository; [TestInitialize] public void Setup() { var config = new ConnectionConfig { ConnectionString = \"测试数据库连接字符串\", DbType = DbType.Sqlite, IsAutoCloseConnection = true }; _db = new SqlSugarClient(config); _db.CodeFirst.InitTables<User>(); _userRepository = new Repository<User>(_db); } [TestMethod] public async Task InsertUser_ShouldReturnTrue() { // Arrange var user = new User { Name = \"测试用户\", Age = 25 }; // Act var result = await _userRepository.InsertAsync(user); // Assert Assert.IsTrue(result); Assert.IsTrue(user.Id > 0); } [TestCleanup] public void Cleanup() { _db?.Dispose(); }}

总结

SqlSugar是一个功能强大、性能优异的.NET ORM框架,具有以下优势:

主要优点

  1. 易于学习:简洁的API设计,完善的中文文档
  2. 高性能:优化的SQL生成和执行机制
  3. 功能丰富:支持多种数据库操作和高级功能
  4. 灵活配置:支持多种配置方式和扩展点
  5. 活跃社区:持续更新和维护,社区支持良好

适用场景

  • 中小型项目:快速开发,简单易用
  • 高性能要求:批量操作,缓存支持
  • 多数据库环境:跨数据库平台开发
  • 国产化项目:支持国产数据库

注意事项

  1. 版本选择:根据项目需求选择合适的版本
  2. 性能监控:合理使用日志和监控功能
  3. 安全考虑:注意SQL注入防护和权限控制
  4. 测试覆盖:编写充分的单元测试和集成测试

SqlSugar为.NET开发者提供了一个优秀的数据访问解决方案,通过合理使用其功能特性,可以大大提高开发效率和应用性能。在实际项目中,建议结合具体业务需求,选择合适的功能和配置,以达到最佳的开发体验和运行效果。