10.1. SqlSugar 集成
温馨提醒
在 Furion
包中默认集成了 EFCore
,如果不使用 EFCore
,可安装纯净版 Furion.Pure
代替 Furion
,这样可以忽略本章节直接按照 SqlSugar
官方文档使用。
10.1.1 关于 SqlSugar
SqlSugar
是 .NET/C# 平台非常优秀的 ORM
框架,目前 Nuget
总下载突破 700K,Github 关注量也高达 3.2K,是目前当之无愧的国产优秀 ORM 框架之一。
SqlSugar
官方地址:http://www.donet5.com/
SqlSugar
与 EF 优势: 性能比 EF 更快、语法上手更容易
SqlSugar
与 Dapper 优势: SqlSugar 功能更加丰富,性能丝毫不逊色于 Dapper,并且批量操作性能更好
10.1.2 如何集成
在 Furion
框架中,已经推出 SqlSugar
拓展包 Furion.Extras.DatabaseAccessor.SqlSugar。
10.1.2.1 注册 SqlSugar
服务
使用非常简单,只需要在 Startup.cs
中添加 services.AddSqlSugar(config)
即可。如:
// =====配置单库=====
services.AddSqlSugar(new ConnectionConfig
{
ConnectionString = "Server=.xxxxx",//连接符字串
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute//从特性读取主键自增信息
});
// =====配置多库=====
List<ConnectionConfig> connectConfigList = new List<ConnectionConfig>();
//数据库1
connectConfigList.Add(new ConnectionConfig
{
ConnectionString = "链接字符串1",
DbType = DbType.MySql,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute,
ConfigId = "0",
AopEvents = new AopEvents
{
//多库状态下每个库必须单独绑定打印事件,否则只会打印第一个库的sql日志
OnLogExecuting = (sql, pars) =>
{
Console.WriteLine(SqlProfiler.ParameterFormat(sql, pars));
Console.WriteLine();
}
}
});
//数据库2
connectConfigList.Add(new ConnectionConfig
{
ConnectionString = "链接字符串2",
DbType = DbType.MySql,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute,
ConfigId = "1",
AopEvents = new AopEvents
{
//多库状态下每个库必须单独绑定打印事件,否则只会打印第一个库的sql日志
OnLogExecuting = (sql, pars) =>
{
Console.WriteLine(SqlProfiler.ParameterFormat(sql, pars));
Console.WriteLine();
}
}
});
services.AddSqlSugar(connectConfigList.ToArray());
同时也可以添加更多配置,如: ps:多库状态下每个库必须单独绑定打印事件,否则只会打印第一个库的sql日志(参考上面的多库配置)
services.AddSqlSugar(connectConfigList.ToArray(),
db =>
{
//处理日志事务
db.Aop.OnLogExecuting = (sql, pars) =>
{
Console.WriteLine(sql);
Console.WriteLine(string.Join(",", pars?.Select(it => it.ParameterName + ":" + it.Value)));
Console.WriteLine();
App.PrintToMiniProfiler("SqlSugar", "Info", sql + "\r\n" + db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
};
});
安装拓展包位置
在 Furion
框架中,推荐将拓展包 Furion.Extras.DatabaseAccessor.SqlSugar
安装到 Furion.Core
层中。
10.1.3 基本使用
在使用之前,我们可以通过构造函数注入 ISqlSugarRepository
接口,如:
private readonly ISqlSugarRepository repository; // 仓储对象:封装简单的CRUD
private readonly SqlSugarClient db; // 核心对象:拥有完整的SqlSugar全部功能
public PersonService(ISqlSugarRepository sqlSugarRepository)
{
repository = sqlSugarRepository;
db = repository.Context; // 推荐操作
}
10.1.4 数据库操作示例
// ================== SqlSugarClient ================
//查询功能
var data1 =db.Queryable<Student>().First(it=>it.Id==1); //db.GetById(1);
var data2 = db.Queryable<Student>().ToList();// db.GetList();
// ================== 简单仓储 ================
//插入
db.Insert(insertObj);
var id = db.InsertReturnIdentity(insertObj);
db.AsInsertable(insertObj).ExecuteCommand();
//删除
db.Delete(insertObj);
db.Delete(it => it.Id == 1);
//更新
db.Update(insertObj);
db.Update(it => new Order() { Name = "a", }, it => it.Id == 1);
//异步方法用法
db.Insert(insertObj);//同步
db.InsertAsync(insertObj);//异步
//切换仓储
var orderRespository=db.GetSimpleClient<Order>();
orderRespository.Insert(Order);
10.1.5 SqlSugarClient 操作示例
10.1.5.1 基础查询
//查询所有
var getAll = db.Queryable<Student>().ToList();
//查询前10
var top10= db.Queryable<Student>().Take(10).ToList();
//查询单条
var getFirst = db.Queryable<Student>().First(it=>it.Id==1);
//with nolock
var getAllNoLock = db.Queryable<Student>().With(SqlWith.NoLock).ToList();
//根据主键查询
var getByPrimaryKey = db.Queryable<Student>().InSingle(2);
//查询总和
var sum = db.Queryable<Student>().Sum(it=>it.Id);
//是否存在
var isAny = db.Queryable<Student>().Where(it=>it.Id==-1).Any();
//模糊查
var list2 = db.Queryable<Order>().Where(it =>it.Name.Contains("jack")).ToList();
10.1.5.2 联表查询
var list = db.Queryable<Student, School>((st, sc) => new JoinQueryInfos(
JoinType.Left,st.SchoolId==sc.Id))
.Select((st,sc)=>new{Id=st.Id,Name=st.Name,SchoolName=sc.Name}).ToList();
生成的Sql如下:
SELECT [st].[ID] AS [id] ,
[st].[Name] AS [name] ,
[sc].[Name] AS [schoolName] FROM [STudent] st
Left JOIN School sc ON ( [st].[SchoolId] =[sc].[Id])
10.1.5.3 分页查询
int pageIndex = 1;
int pageSize = 20;
int totalCount=0;
var page = db.Queryable<Student>().ToPageList(pageIndex, pageSize, ref totalCount);
更多查询用法 : http://www.donet5.com/Home/Doc?typeId=1185
10.1.5.4 插入
//可以是 类 或者 List<类>
db.Insertable(insertObj).ExecuteCommand();
//插入返回自增列
db.Insertable(insertObj).ExecuteReturnIdentity();
//可以是 Dictionary 或者 List<Dictionary >
var dc= new Dictionary<string, object>();
dt.Add("name", "1");
dt.Add("CreateTime", null);
db.Insertable(dc).AS("student").ExecuteCommand();
//DataTable插入
Dictionary<string,object> dc= db.Utilities.DataTableToDictionary(dataTable);//转成字典就可以按上面的字典更新了
db.Insertable(dc).AS("student").ExecuteReturnIdentity();
//实体可以配置主键和自增列
public class Student
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public int? SchoolId { get; set; }
public string Name { get; set; }
}
更多插入用法: http://www.donet5.com/Home/Doc?typeId=1193
10.1.5.5 更新
实体配置参考插入,只需要配置主键即可
//根据主键更新单条 参数 Class
var result= db.Updateable(updateObj).ExecuteCommand();
//不更新 Name 和TestId
var result=db.Updateable(updateObj).IgnoreColumns(it => new { it.CreateTime,it.TestId }).ExecuteCommand()
//只更新 Name 和 CreateTime
var result=db.Updateable(updateObj).UpdateColumns(it => new { it.Name,it.CreateTime }).ExecuteCommand();
//根据表达式更新
var result71 = db.Updateable<Order>()
.SetColumns(it => it.Name == "a")
.SetColumnsIF(p!=null ,it => it.CreateTime == p.Value)//当p不等于null更新createtime列
.Where(it => it.Id == 11).ExecuteCommand();
更多更新用法: http://www.donet5.com/Home/Doc?typeId=1191
10.1.5.6 删除
实体配置参考插入,只需要配置主键即可
//根据实体删除
db.Deleteable<Student>().Where(new Student() { Id = 1 }).ExecuteCommand();
//根据主键删除
db.Deleteable<Student>().In(1).ExecuteCommand();
//根据表达式删除
db.Deleteable<Student>().Where(it => it.Id == 1).ExecuteCommand();
更多删除用法: http://www.donet5.com/Home/Doc?typeId=1195
10.1.6 Sql 查询
//sql分页
var list = db.SqlQueryable<Student>("select * from student").ToPageList(1, 2,ref total);
//原生Sql用法
var dt=db.Ado.GetDataTable("select * from table where id=@id and name=@name",new List<SugarParameter>(){
new SugarParameter("@id",1),
new SugarParameter("@name",2)
});
//参数2
var dt=db.Ado.GetDataTable("select * from table where id=@id and name=@name",new{id=1,name=2});
//存储过程用法
var nameP= new SugarParameter("@name", "张三");
var ageP= new SugarParameter("@age", null, true);//设置为output
var dt = db.Ado.UseStoredProcedure().GetDataTable("sp_school",nameP,ageP);
方法名 | 描述 | 返回值 |
---|---|---|
SqlQuery< T > | 查询所有返回实体集合 | List |
SqlQuery<T,T2> | 可以返回 2 个结果集 | Tuple<List, List> |
SqlQuerySingle | 查询第一条记录 | T |
GetDataTable | 查询所有 | DataTable |
GetDataReader | 读取 DR 需要手动释放 DR | DataReader |
GetDataSetAll | 获取多个结果集 | DataSet |
ExecuteCommand | 返回受影响行数,一般用于增删改 | int |
GetScalar | 获取首行首列 | object |
GetString | 获取首行首列 | string |
GetInt | 获取首行首列 | int |
GetLong | 获取首行首列 | long |
GetDouble | 获取首行首列 | Double |
GetDecimal | 获取首行首列 | Decimal |
GetDateTime | 获取首行首列 | DateTime |
想了解更多 SqlSugar
知识可查阅 SqlSugar 官网。
10.1.7 打印 sql
到 Swagger
services.AddSqlSugar(new ConnectionConfig
{
ConnectionString = "Server=.xxxxx",//连接符字串
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute//从特性读取主键自增信息
},
db =>
{
db.Aop.OnLogExecuting = (sql, pars) =>
{
//方法一
App.PrintToMiniProfiler("SqlSugar", "Info", sql + "\r\n" +string.Join(",", pars?.Select(it => it.ParameterName + ":" + it.Value)));
//方法二:Furion对上述用法进行二次封装 建议方式 Sql参数会直接写入到生成Sql中
App.PrintToMiniProfiler("SqlSugar","Info",SqlProfiler.ParameterFormat(sql,pars));
};
});
10.1.8 Oracle
注意事项
注意 .NET5 用户需要在 API 或者项目解决方案 .csproj
文件加以下一行代码:
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
10.1.9 反馈与建议
与我们交流
给 Furion 提 Issue。