SqlSugarORM框架安装配置使用详解
发布于2026-07-23 阅读(0)
# SqlSugar:一款让.NET开发者爱不释手的国产ORM框架
在.NET生态圈里,ORM框架的选择其实不少,但要说哪款最接地气、最懂中国开发者,SqlSugar绝对能排进前三。它由国内开发者维护,轻量、高效,而且对多数据库的支持做得相当扎实——从SQL Server到MySQL,从PostgreSQL到Oracle,甚至连达梦、人大金仓这些国产数据库也一并覆盖。说白了,它就是那种“拿来就能用,用了就回不去”的工具。
## 为什么选择SqlSugar?
先说说它最吸引人的几个点:
- **轻量级**:框架体积小,启动速度快,不像某些“重型武器”那样拖泥带水。
- **高性能**:SQL生成和执行机制经过多次优化,批量操作时优势尤其明显。
- **易用性**:API设计简洁,学习成本很低,有经验的开发者几乎可以零障碍上手。
- **多数据库支持**:主流数据库全覆盖,国产数据库也位列其中。
- **中文文档**:这一点太重要了——完善的官方文档和活跃的社区,遇到问题翻翻文档或者群里问一句,基本都能解决。
## 特性与优势
### 核心特性
**多数据库支持**
SqlSugar内置了对多种数据库的支持,而且切换起来非常方便。除了常见的SQL Server、MySQL、PostgreSQL、Oracle、SQLite,还专门适配了达梦、人大金仓等国产数据库。对于需要在不同数据库间切换的项目来说,这简直是救命的功能。
**丰富的查询方式**
Lambda表达式查询、原生SQL、存储过程调用、动态查询构建……基本上你能想到的查询方式,它都提供了。而且Lambda表达式的写法非常直观,写起来比拼接字符串舒服太多了。
**代码生成功能**
根据数据库表自动生成实体类、仓储层代码,还能自定义模板。对于快速搭建项目骨架来说,效率提升不是一点半点。
**事务管理**
自动事务、手动控制、分布式事务支持,该有的都有。而且事务的API设计得很顺手,不容易出错。
### 性能优势
说到性能,直接上代码感受一下:
```csharp
// 高性能的批量操作
var users = new List
();
for (int i = 0; i < 10000; i++)
{
users.Add(new User { Name = $"User{i}", Age = 20 + i % 50 });
}
// 批量插入,性能优异
db.Insertable(users).ExecuteCommand();
```
一万条数据,一秒钟搞定,这在传统逐条插入的场景下简直是降维打击。
## 安装与配置
### NuGet包安装
安装核心包和对应的数据库扩展包,命令很简单:
```csharp
# 核心包
Install-Package SqlSugar
# 特定数据库扩展
Install-Package SqlSugar.SqlServer
Install-Package SqlSugar.MySql
Install-Package SqlSugar.PostgreSQL
```
### 基础配置
配置一个数据库连接,几行代码足矣:
```csharp
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}"))}");
};
```
`IsAutoCloseConnection` 这个配置很实用,每次查询完自动关闭连接,省去了手动管理的麻烦。日志功能也方便调试,能直接看到生成的SQL语句和参数。
### 多数据库配置
如果项目需要同时连接多个数据库,使用 `SqlSugarScope` 搭配 `ConfigId` 来管理:
```csharp
var configs = new List
{
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]` 和 `[SugarColumn]` 特性来映射数据库表:
```csharp
[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; }
}
```
这里的 `IsIgnore` 很实用——有些实体属性不需要映射到数据库,加个特性就搞定了。
### 基本CRUD操作
增删改查的操作非常直观,几乎不需要额外学习:
```csharp
// 插入
var user = new User { Name = "张三", Age = 25, CreateTime = DateTime.Now };
var id = db.Insertable(user).ExecuteReturnIdentity();
// 查询
var users = db.Queryable().ToList();
var user = db.Queryable().Where(u => u.Id == 1).First();
// 更新
db.Updateable()
.SetColumns(u => new User { Age = 26 })
.Where(u => u.Id == 1)
.ExecuteCommand();
// 删除
db.Deleteable().Where(u => u.Id == 1).ExecuteCommand();
```
## 实体映射
### 特性配置
除了基础的字段映射,SqlSugar还支持更精细的控制,比如字段名映射、精度、JSON字段等:
```csharp
[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 Tags { get; set; }
}
```
`IsJson = true` 这个特性很惊艳——可以直接把 `List` 这样的复杂类型映射到数据库的JSON字段,读写时自动序列化/反序列化,省去了手写转换的麻烦。
### Fluent API配置
如果不想用特性,也可以使用Fluent API来配置,两种方式任选:
```csharp
db.CodeFirst.ConfigQuery()
.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));
```
### 枚举映射
枚举类型可以直接映射到数据库,配合 `IsEnableUpdateVersionValidation` 还能实现乐观锁:
```csharp
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; }
}
```
## 数据库操作
### 数据库初始化
用代码来创建数据库和表,开发环境一键初始化:
```csharp
// 创建数据库
db.DbMaintenance.CreateDatabase();
// 根据实体创建表
db.CodeFirst.InitTables();
// 检查表是否存在
if (!db.DbMaintenance.IsAnyTable("Users"))
{
db.CodeFirst.InitTables();
}
```
### 表结构管理
动态添加列、删除列、重命名表,这些操作同样支持:
```csharp
// 添加列
db.DbMaintenance.AddColumn("Users", new DbColumnInfo
{
DbColumnName = "Email",
DataType = "varchar",
Length = 100,
IsNullable = true
});
// 删除列
db.DbMaintenance.DropColumn("Users", "TempColumn");
// 重命名表
db.DbMaintenance.RenameTable("OldTableName", "NewTableName");
```
### 索引管理
创建、删除、查询索引,API一致且简洁:
```csharp
// 创建索引
db.DbMaintenance.AddIndex("Users", new string[] { "Name", "Age" });
// 删除索引
db.DbMaintenance.DropIndex("Users", "IX_Users_Name_Age");
// 获取索引信息
var indexes = db.DbMaintenance.GetIndexList("Users");
```
## 查询操作
### Lambda表达式查询
查询是ORM的核心,SqlSugar的Lambda查询写得非常顺手:
```csharp
// 基础查询
var users = db.Queryable()
.Where(u => u.Age > 18)
.OrderBy(u => u.CreateTime)
.ToList();
// 复杂条件查询
var result = db.Queryable()
.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();
```
`WhereIF` 这个扩展方法很实用——条件满足时才加入查询条件,代码干净很多。
### 分页查询
分页有两种方式:`ToPageList` 和 `ToOffsetPage`,前者返回总记录数,后者适合与前端分页组件对接:
```csharp
// 方式一:使用ToPageList
int pageIndex = 1, pageSize = 10;
var pageResult = db.Queryable()
.Where(u => u.Age > 18)
.OrderBy(u => u.Id)
.ToPageList(pageIndex, pageSize);
Console.WriteLine($"总记录数: {pageResult.TotalCount}");
Console.WriteLine($"总页数: {pageResult.TotalPages}");
// 方式二:使用ToOffsetPage
var offsetResult = db.Queryable()
.Where(u => u.Age > 18)
.OrderBy(u => u.Id)
.ToOffsetPage(pageIndex, pageSize);
```
### 联表查询
内连接、左连接,写法都很直观:
```csharp
// 内连接
var result = db.Queryable((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()
.LeftJoin((u, o) => u.Id == o.UserId)
.Select((u, o) => new
{
u.Name,
OrderCount = SqlFunc.IsNull(o.Id, 0)
})
.ToList();
```
### 子查询
子查询的支持也很完善,比如找出订单总额超过1000的用户:
```csharp
var subQuery = db.Queryable()
.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()
.Where(u => SqlFunc.Subqueryable(subQuery)
.Where(s => s.UserId == u.Id && s.TotalAmount > 1000)
.Any())
.ToList();
```
### 聚合查询
分组聚合、Ha ving子句,一个不少:
```csharp
// 分组聚合
var groupResult = db.Queryable()
.GroupBy(o => new { o.UserId, o.Status })
.Select(o => new
{
o.UserId,
o.Status,
Count = SqlFunc.Count(o.Id),
TotalAmount = SqlFunc.Sum(o.Amount),
A vgAmount = SqlFunc.A vg(o.Amount),
MaxAmount = SqlFunc.Max(o.Amount),
MinAmount = SqlFunc.Min(o.Amount)
})
.ToList();
// Ha ving子句
var ha vingResult = db.Queryable()
.GroupBy(o => o.UserId)
.Ha ving(o => SqlFunc.Sum(o.Amount) > 5000)
.Select(o => new
{
UserId = o.UserId,
TotalAmount = SqlFunc.Sum(o.Amount)
})
.ToList();
```
## 高级功能
### 事务管理
事务有两种风格:手动控制和使用 `using` 语句自动管理:
```csharp
// 自动事务
try
{
db.BeginTran();
// 执行多个操作
db.Insertable(user).ExecuteCommand();
db.Updateable(order).ExecuteCommand();
db.Deleteable().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(); // 提交事务
}
```
### 批量操作
批量插入、批量更新,用 `Fastest` 方法实现极致性能:
```csharp
// 批量插入
var users = new List();
for (int i = 0; i < 10000; i++)
{
users.Add(new User { Name = $"User{i}", Age = 20 + i % 50 });
}
// 高性能批量插入
db.Fastest().BulkCopy(users);
// 批量更新
var updateUsers = db.Queryable().Where(u => u.Age < 25).ToList();
updateUsers.ForEach(u => u.Age += 1);
db.Fastest().BulkUpdate(updateUsers);
// 批量删除
db.Deleteable().Where(u => u.Age > 60).ExecuteCommand();
```
### 缓存功能
查询结果可以缓存,支持自定义缓存键和过期时间:
```csharp
// 查询缓存
var cachedUsers = db.Queryable()
.Where(u => u.Status == UserStatus.Active)
.WithCache(60) // 缓存60秒
.ToList();
// 自定义缓存键
var customCachedUsers = db.Queryable()
.Where(u => u.Age > 18)
.WithCache("active_users", 300) // 自定义缓存键,缓存5分钟
.ToList();
// 清除缓存
db.RemoveDataCache("active_users");
```
### 读写分离
配置主从库后,查询自动路由到从库,写操作走主库:
```csharp
var configs = new List
{
new ConnectionConfig
{
ConfigId = "master",
ConnectionString = "主库连接字符串",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true
},
new ConnectionConfig
{
ConfigId = "sla ve1",
ConnectionString = "从库1连接字符串",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
Sla veConnectionConfigs = new List
{
new Sla veConnectionConfig { HitRate = 50 }, // 50%命中率
}
}
};
var db = new SqlSugarScope(configs);
// 查询自动使用从库
var users = db.Queryable().ToList();
// 强制使用主库查询
var masterUsers = db.GetConnection("master").Queryable().ToList();
```
### 多租户支持
通过表名映射实现多租户,切换租户后自动查询对应的分表:
```csharp
// 配置多租户
db.SetTenantTable("tenant1", "Users_Tenant1");
db.SetTenantTable("tenant2", "Users_Tenant2");
// 切换租户
db.ChangeTenant("tenant1");
var tenant1Users = db.Queryable().ToList(); // 查询Users_Tenant1表
db.ChangeTenant("tenant2");
var tenant2Users = db.Queryable().ToList(); // 查询Users_Tenant2表
```
## 性能优化
### 查询优化
几个实用的优化技巧:
```csharp
// 1. 使用异步操作
var usersAsync = await db.Queryable()
.Where(u => u.Age > 18)
.ToListAsync();
// 2. 只查询需要的字段
var userNames = db.Queryable()
.Select(u => u.Name)
.ToList();
// 3. 使用NoLock(SQL Server)
var noLockUsers = db.Queryable()
.With(SqlWith.NoLock)
.ToList();
// 4. 分页查询大数据量
var largeDataPage = db.Queryable()
.OrderBy(u => u.Id)
.ToOffsetPage(1, 1000);
```
### 连接池优化
通过 `MoreSettings` 配置缓存、Nolock默认行为等:
```csharp
var config = new ConnectionConfig
{
ConnectionString = "连接字符串",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
// 连接池配置
ConfigureExternalServices = new ConfigureExternalServices
{
DataInfoCacheService = new HttpRuntimeCache(), // 使用缓存
SqlFuncServices = new List() // 自定义SQL函数
},
// 性能配置
MoreSettings = new ConnMoreSettings
{
IsAutoRemoveDataCache = true, // 自动清理缓存
IsWithNoLockQuery = true, // 默认使用NoLock
DefaultCacheDurationInSeconds = 600 // 默认缓存时间
}
};
```
### SQL优化建议
常见的性能坑,SqlSugar都帮你想好了:
```csharp
// 1. 避免N+1查询问题
var usersWithOrders = db.Queryable()
.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()
.Where(u => u.Email == "test@example.com") // 确保Email字段有索引
.First();
```
## 最佳实践
### 1. 仓储模式实现
定义一个通用的仓储接口和实现,方便依赖注入:
```csharp
public interface IRepository where T : class, new()
{
Task GetByIdAsync(object id);
Task> GetAllAsync();
Task InsertAsync(T entity);
Task UpdateAsync(T entity);
Task DeleteAsync(object id);
}
public class Repository : IRepository where T : class, new()
{
private readonly ISqlSugarClient _db;
public Repository(ISqlSugarClient db)
{
_db = db;
}
public async Task GetByIdAsync(object id)
{
return await _db.Queryable().InSingleAsync(id);
}
public async Task> GetAllAsync()
{
return await _db.Queryable().ToListAsync();
}
public async Task InsertAsync(T entity)
{
return await _db.Insertable(entity).ExecuteCommandAsync() > 0;
}
public async Task UpdateAsync(T entity)
{
return await _db.Updateable(entity).ExecuteCommandAsync() > 0;
}
public async Task DeleteAsync(object id)
{
return await _db.Deleteable().In(id).ExecuteCommandAsync() > 0;
}
}
```
### 2. 依赖注入配置
在Startup或Program中注册SqlSugarClient和仓储:
```csharp
services.AddSingleton(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>();
logger.LogInformation($"SQL: {sql}");
};
return db;
});
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
```
### 3. 配置管理
将数据库配置抽取到 `appsettings.json` 中,方便不同环境切换:
```csharp
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(Configuration.GetSection("Database"));
```
### 4. 异常处理
实现一个带重试机制的异常处理类,避免临时性数据库故障导致程序崩溃:
```csharp
public class DatabaseExceptionHandler
{
private readonly ILogger _logger;
public DatabaseExceptionHandler(ILogger logger)
{
_logger = logger;
}
public async Task ExecuteWithRetryAsync(Func> 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. 单元测试
使用SQLite内存数据库进行单元测试,速度快且隔离性好:
```csharp
[TestClass]
public class UserRepositoryTests
{
private ISqlSugarClient _db;
private IRepository _userRepository;
[TestInitialize]
public void Setup()
{
var config = new ConnectionConfig
{
ConnectionString = "测试数据库连接字符串",
DbType = DbType.Sqlite,
IsAutoCloseConnection = true
};
_db = new SqlSugarClient(config);
_db.CodeFirst.InitTables();
_userRepository = new Repository(_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 是一个功能全面、性能出色的国产ORM框架,它的优势可以归纳为以下几点:
**主要优点**
1. **易于学习**:API设计简洁,中文文档完善,新手也能快速上手。
2. **高性能**:SQL生成机制经过精心优化,批量操作速度惊人。
3. **功能丰富**:从基本的CRUD到事务、缓存、读写分离、多租户,几乎覆盖了所有常见需求。
4. **灵活配置**:支持特性、Fluent API、配置文件等多种方式,扩展点丰富。
5. **活跃社区**:持续更新维护,遇到问题在社区里很容易找到答案。
**适用场景**
- **中小型项目**:快速开发,简单易用,不需要复杂配置。
- **高性能要求**:批量操作、缓存支持,能应对高并发场景。
- **多数据库环境**:跨数据库平台开发,切换成本极低。
- **国产化项目**:对达梦、人大金仓等国产数据库的深度支持,是替代国外ORM的绝佳选择。
**注意事项**
1. **版本选择**:根据项目需求选择合适的版本,LTS版本更稳定。
2. **性能监控**:合理使用日志和监控功能,避免生产环境日志过多影响性能。
3. **安全考虑**:注意SQL注入防护(虽然ORM本身已经做了处理,但原生SQL查询仍需谨慎),以及权限控制。
4. **测试覆盖**:编写充分的单元测试和集成测试,尤其是数据库迁移和批量操作部分。
总的来说,SqlSugar 为.NET开发者提供了一套非常顺手的数据访问解决方案。它不像某些大型框架那样“重”,也不像微ORM那样功能缺失,而是在易用性和功能丰富度之间找到了很好的平衡。在实际项目中,结合具体业务需求,选择合适的特性和配置,开发效率和运行效果都能得到显著提升。
本文转载于:https://www.jb51.net/aspnet/347367mmr.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。