.NET ORM框架 SqlSugar4.0 功能快速预览【开源】
SqlSugar 4.0 ORM框架的优势
为了未来能够更好的支持多库分布式的存储,并行计算等功能,将SqlSugar3.x全部重写,现有的架构可以轻松扩展多库。
源码下载:
https://github.com/sunkaixuan/SqlSugar
1.性能
性能最好的ORM之一,具有超越Dapper的性能 ,走的是EMIT够构中间语言动态编译到程序集,完成高性能的实体绑定,达到原生水平。
测试方式用Realease模式,Realease DLL 进行的车轮战

2.功能
除了EF以外可以说的是功能最大的ORM框架
支持 DbFirst、CodeFirst、数据库维护、链式查询、链式更新、链式删除、链式插入、实体属性、复杂模型的查询、ADO.NET。特别是批量等功能都是货真价实的并非循环操作。
SqlSugar 4.0版本 6月底支持SqlSever的Core版 ,预计7月份支持多库,8月分开始分布式ORM的开发。 (3.x版本已经支持了4种数据库,相对稳定功能简单)
3.语法
完美的语法,可以秒杀现有所有ORM框架
SqlSugar 4.0 三表查询并分页
int total=0;
var list8 = db.Queryable<Student,School,School>((st,sc,sc2) =>st.SchoolId ==sc.Id&&sc.Id ==sc2.Id)
.Select((st, sc, sc2) =>new{st.Name,st.Id,schoolName = sc.Name})
.ToPageList(, 2,ref total)
EF 二表查询并分页
var queryable = (from a in StudentList
join b in SchoolList1
on a.Id equals b.Id into b1
from b2 in b1.DefaultIfEmpty()
select new
{
a.Id,
a.Name,
t = b2.Name });
var listp = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
var total = queryable.Count();
从上面的语法可以看出两者之前的差距,3表查询比EF2表查询还要简洁
我们在来看一下条件拼接的例子
SqlSugar语法:
var list = db.Queryable<Student>()
.WhereIF(!string.IsNullOrEmpty(a),it => it.Name == a)
.WhereIF(!string.IsNullOrEmpty(b), it => it.Name == b).ToList();
EF语法:
var queryable = db.Queryable<Student>();
if (!string.IsNullOrEmpty(a)) {
queryable = queryable.Where(it => it.Name == a);
}
if (!string.IsNullOrEmpty(b)) {
queryable = queryable.Where(it => it.Name == b);
}
var list = queryable.ToList();
是不是简单很多呢?
4.轻量级
总大小只有200多K,比EF的一个小插件都小,EF主体有5M
5.持续更新
本来4.X预计3月份就可以开发完成的,因为换了新公司半年都是996工作制,我只有周日和晚上有时间开发,可以说我基本都没有休息过。下半年工作不会这么紧,我的时间会更充足一些。
功能详解
SqlSugar 4.X 总共有九大核心功能,并且都设计为链式操作,链式操作有什么好处?
第一链式操作可以减少方法的重载
第二链式操作可以让代码更加易读,举个例子一个方法有很多重载,你在写的代码就不清楚这些重载是做嘛的,需要F12到方法主体去看备注。
例如:第一种写法就能清楚的知道 是否建创属性,并且只创建Student这张表的文件,第二种方法虽然简单不易读
db.DbFirst.IsCreateAttribute().Where("Student").CreateClassFile("c:\\Demo\\5");
db.DbFirst.CreateClassFile(true,"Student","c:\\Demo\\5");
第三链式操更具有扩展性 例如有1234 我可以1和2一组,234一组 1和4一组,如果是重载的方式至少要有十个以上的重载后期将很难维护,功能越多后期易读越差,也不灵活。

1.Queryable
查询的核心对象,可以实现多表查询,分组查询,分页,支持SqlFunc函数和拉姆达解析,除EF外也是对拉姆达解析支持最好的ORM之一
简单查询
查询所有
var getAll = db.Queryable<Student>().ToList();
无锁查询
var getAllNoLock = db.Queryable<Student>().With(SqlWith.NoLock).ToList();
根据主键查询
var getByPrimaryKey = db.Queryable<Student>().InSingle()
查询单条没有数据返回NULL, Single超过1条会报错,First不会
var getSingleOrDefault = db.Queryable<Student>().Single();
var getFirstOrDefault = db.Queryable<Student>().First();
IN查询
//Id In (1,2,3)
var in1 = db.Queryable<Student>().In(it=>it.Id,new int[] { , , }).ToList(); //主键 In (1,2,3)
var in2 = db.Queryable<Student>().In(new int[] { , , }).ToList(); //Id In (1,2)
int[] array = new int[] { , };
var in3 = db.Queryable<Student>().Where(it=>array.Contains(it.Id)).ToList();
NOT IN查询
var in3 = db.Queryable<Student>().Where(it=>!array.Contains(it.Id)).ToList();
多条件查询
var getByWhere = db.Queryable<Student>().Where(it => it.Id == || it.Name == "a").ToList();
使用函数 SqlFunc类
var getByFuns = db.Queryable<Student>().Where(it => SqlFunc.IsNullOrEmpty(it.Name)).ToList();
可以使用 SUM MAX MIN AVG查询单个字段
var sum = db.Queryable<Student>().Sum(it => it.Id);
Between 1 and 20
var between = db.Queryable<Student>().Where(it => SqlFunc.Between(it.Id, , )).ToList();
使用 AS 取新的表名
var getListByRename = db.Queryable<School>().AS("Student").ToList();
排序
var getAllOrder = db.Queryable<Student>()
.OrderBy(it => it.Id)//asc
.OrderBy(it => it.Name, OrderByType.Desc)//desc
.ToList()
是否存在这条记录
var isAny = db.Queryable<Student>().Where(it => it.Id == -).Any();
var isAny2 = db.Queryable<Student>().Any(it => it.Id == -);
获取同一天的记录
var getTodayList = db.Queryable<Student>().Where(it => SqlFunc.DateIsSame(it.CreateTime, DateTime.Now)).ToList();
多表查询
//LEFT JOIN
var list = db.Queryable<Student, School>((st, sc) => new object[] {
JoinType.Left,st.SchoolId==sc.Id
})
.Where(st => st.Name == "jack").ToList(); //三表 LEFT JOIN
var list2 = db.Queryable<Student, School, Student>((st, sc, st2) => new object[] {
JoinType.Left,st.SchoolId==sc.Id,
JoinType.Left,st.SchoolId==st2.Id
})
.Where((st, sc, st2) => st2.Id == || sc.Id == || st.Id == ).ToList(); //返回 List<ViewModelStudent>
var list3 = db.Queryable<Student, School>((st, sc) => new object[] {
JoinType.Left,st.SchoolId==sc.Id
}).Select((st, sc) => new ViewModelStudent { Name = st.Name, SchoolId = sc.Id }).ToList(); //join Order By (order by st.id desc,sc.id desc)
var list4 = db.Queryable<Student, School>((st, sc) => new object[] {
JoinType.Left,st.SchoolId==sc.Id
})
.OrderBy(st => st.Id, OrderByType.Desc)
.OrderBy((st, sc) => sc.Id, OrderByType.Desc)
.Select((st, sc) => new ViewModelStudent { Name = st.Name, SchoolId = sc.Id }).ToList();
多表查询简化,与JOIN的方式高低搭配,如果不需要LEFT JOIN可以简写成下面的语句
var list5 = db.Queryable<Student, School>((st, sc) => st.SchoolId == sc.Id)
.Select((st,sc)=>new {st.Name,st.Id,schoolName=sc.Name}).ToList(); //三表查询
var list6 = db.Queryable<Student, School,School>((st, sc,sc2) => st.SchoolId == sc.Id&&sc.Id==sc2.Id)
.Select((st, sc,sc2) => new { st.Name, st.Id, schoolName = sc.Name,schoolName2=sc2.Name }).ToList();
//三表查询分页
var list8 = db.Queryable<Student, School, School>((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id)
.OrderBy(st=>st.Id)
.Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToPageList(, );
分组查询
var group = db.Queryable<Student>().GroupBy(it => it.Id)
.Having(it => SqlFunc.AggregateCount(it.Id) > )
.Select(it => new { id = SqlFunc.AggregateCount(it.Id) }).ToList();
根据字段分组取第一条,这个非常的好用
var list3 = db.Queryable<Student>()
.PartitionBy(it => new { it.Id, it.Name }).Take().ToList();
实体转换支持2级模型
var s5 = db.Queryable<Student>().Select(it => new ViewModelStudent { Student = it, Name = it.Name }).ToList();
//实体结构
public class ViewModelStudent {
public Student Student{get;set;}
pulic string Name{get;set;}
}
如果你是字段串拼接爱好者你也可以这样与拉姆达混用,或者纯拼SQL
var join3 = db.Queryable("Student", "st")
.AddJoinInfo("School", "sh", "sh.id=st.schoolid")
.Where("st.id>@id")
.AddParameters(new { id = })
.Select("st.*").ToList();
支持的原生函数
.ToString .Contains .Length .ToLower .ToUpper .ToSubstring .Equals .HasValue .Replace .EndsWith .StartsWith .Trim
支持的自定义函数
三元判段 ,相当于 it.id==1?1:2
SqlFunc.IIF(it.Id == , , )
判段是NULL或者空
SqlFunc.IsNullOrEmpty(object thisValue)
判段不是NULL并且不是空
SqlFunc.HasValue(object thisValue)
判段大于0并且不等于NULL
SqlFunc.HasNumber(object thisValue)
转小写
SqlFunc.ToLower(object thisValue)
转大写
SqlFunc.ToUpper(object thisValue)
去前后空格
SqlFunc.Trim(object thisValue)
模糊查询 like %@p%
SqlFunc.Contains(string thisValue, string parameterValue)
也可以使用 .Where(it=>it.Name.Contains("a"));
In操作 thisValue={1,2,3} 生成的Sql就是 paramterValie in (1,2,3)
SqlFunc.ContainsArray(object[] thisValue, string parameterValue)
也可以使用 .Where(it=>Array.Contains(it.Id));
Not In 操作
.Where(it=>!Array.Contains(it.Id));
模糊查询 like @p%
SqlFunc.StartsWith(object thisValue, string parameterValue
模糊查询 like %@p
SqlFunc.EndsWith(object thisValue, string parameterValue)
等于
SqlFunc.Equals(object thisValue, object parameterValue)
是否是同一天
SqlFunc.DateIsSame(DateTime date1, DateTime date2)
是否是同一时间 (dataType 可以是年、月、天、小时、分钟、秒和毫秒)
SqlFunc.DateIsSame(DateTime date1, DateTime date2, DateType dataType)
在当前时间加一定时间(dataType 可以是年、月、天、小时、分钟、秒和毫秒)
SqlFunc.DateAdd(DateTime date, int addValue, DateType dataType)
在当前时间加N天
SqlFunc.DateAdd(DateTime date, int addValue)
获取当前时间的年、月、天、小时、分钟、秒或者毫秒
SqlFunc.DateValue(DateTime date, DateType dataType)
范围判段
SqlFunc.Between(object value, object start, object end)
类型转换
SqlFunc.ToInt32(object value)
SqlFunc.ToInt64(object value)
SqlFunc.ToDate(object value)
SqlFunc.ToString(object value)
SqlFunc.ToDecimal(object value)
SqlFunc.ToGuid(object value)
SqlFunc.ToDouble(object value)
SqlFunc.ToBool(object value)
截取字符串
SqlFunc.Substring(object value, int index, int length)
替换字符串
SqlFunc.Replace(object value, string oldChar, string newChar)
获取字符串长度
SqlFunc.Length(object value) { throw new NotImplementedException(); }
聚合函数
SqlFunc.AggregateSum<TResult>(TResult thisValue)
SqlFunc.AggregateAvg<TResult>(TResult thisValue)
SqlFunc.AggregateMin(TResult thisValue)
SqlFunc.AggregateMax<TResult>(TResult thisValue)
SqlFunc.AggregateCount<TResult>(TResult thisValue)
如果还有不支持的可以写字符串
db.Queryable<Student>().Where("xxx(xx)")
2.Updateable
updateable主要功能有批量更新、单条更新、指定更新列、排除更新列、根据拉姆达更新、根据实体更新等操作
根据实体更新(主键要有值,主键是更新条件)
var t1 = db.Updateable(updateObj).ExecuteCommand();
只更新实体里面的Name列(主键要有值,主键是更新条件)
var t3 = db.Updateable(updateObj).UpdateColumns(it => new { it.Name }).ExecuteCommand();
更新 Name和 TestId 以外的所有列 (主键要有值,主键是更新条件)
var t4 = db.Updateable(updateObj)
.IgnoreColumns(it => new { it.Name, it.TestId }).ExecuteCommand();
更新NAME
var t5 = db.Updateable(updateObj)
.IgnoreColumns(it => it=="name" ).With(SqlWith.UpdLock).ExecuteCommand();
使用锁
var t6 = db.Updateable(updateObj).With(SqlWith.UpdLock).ExecuteCommand();
批量更新(主键要有值,主键是更新条件)
List<Students> list=GetList();
var t7 = db.Updateable(list).ExecuteCommand();
实体更新,并且给指定列重新赋值
var t8 = db.Updateable(updateObj)
.ReSetValue(it => it.Name == (it.Name + )).ExecuteCommand();
更新实体,更新条件是根据表达示
var t9 = db.Updateable(updateObj).Where(it => it.Id == ).ExecuteCommand();
根据表达式中的列更新 ,指定列并赋值的更新,比较常用
var t10 = db.Updateable<Student>()
.UpdateColumns(it => new Student() { Name = "a", CreateTime = DateTime.Now })
.Where(it => it.Id == ).ExecuteCommand();
别名表
db.Updateable<School>().AS("Student")
.UpdateColumns(it => new School() { Name = "jack" })
.Where(it => it.Id == ).ExecuteCommand();
//Update Student set Name='jack' Where Id=1
是NULL的列不更新
db.Updateable(updateObj).Where(true).ExecuteCommand();
3.Insertable
Insertable主要功能有 批量插入、单条插入、指定插入列、排除插入列等功能
插入并返回受影响行数用ExecuteCommand
var t2 = db.Insertable(insertObj).ExecuteCommand();
插入并返回自增列用ExecuteReutrnIdentity
var t3 = db.Insertable(insertObj).ExecuteReutrnIdentity();
只插入列 Name和SchoolId
var t4 = db.Insertable(insertObj).InsertColumns(it => new { it.Name, it.SchoolId }).ExecuteReutrnIdentity();
不插入列 Name和TestId
var t5 = db.Insertable(insertObj).IgnoreColumns(it => new { it.Name, it.TestId }).ExecuteReutrnIdentity();
根据条件指定不插入列
var t6 = db.Insertable(insertObj).IgnoreColumns(it => it == "Name" || it == "TestId").ExecuteReutrnIdentity();
使用锁
var t8 = db.Insertable(insertObj).With(SqlWith.UpdLock).ExecuteCommand();
可以设置NULL列不插入和是否强制插入自增列
var t9 = db.Insertable(insertObj2)
.Where(true/* Is no insert null */, true/*off identity*/)
.ExecuteCommand();
批量插入
var insertObjs = new List<Student>();
var s9 = db.Insertable(insertObjs.ToArray()).ExecuteCommand();
Deleteable
根据主键删除、单条删除、条件删除、表达式删除等功能
根据实体删除(实体内主键一定要有值)
var t0 = db.Deleteable<Student>().Where(new Student() { Id = }).ExecuteCommand();
根据实体集删除
var t1 = db.Deleteable<Student>().Where(new List<Student>() { new Student() { Id = } }).ExecuteCommand();
使用锁
var t2 = db.Deleteable<Student>().With(SqlWith.RowLock).ExecuteCommand();
根据主键删除
var t3 = db.Deleteable<Student>().In().ExecuteCommand();
根据主键批量删除
var t4 = db.Deleteable<Student>().In(new int[] { , }).ExecuteCommand();
根据表达式删除
var t5 = db.Deleteable<Student>().Where(it => it.Id == ).ExecuteCommand();
其它功能的一些简介
因为功能太多九大功能只讲了4大功能的用法,其它功能我就简单描述一下
DbFirst:用于创建实体、支持模型自定义、可以生成全部表的实体、也可以指定表和支持生成属性和默认值
CodeFirst:支持通过类生成实体、主键、自增列、支持表的备份和字段名称的修改
Ado.Net: 支持SqlQuery<T> 一系列 原生SQL操作 支持事务、存储过程输出参数等功能
DbMaintenance:数据库的维护操作 支持表备份、库备份、添加表、添加列、获取表信息 、根据表获取主键等相关数据库层面的操作
EntityProvider:获取实体类的相关信息
另外支持了复杂模型的用法:
var students = db.Queryable<CMStudent>().ToList();
if (students != null)
{
foreach (var item in students)
{
Console.WriteLine(item.SchoolName); Console.WriteLine(item.SchoolSingle.Name); Console.WriteLine(item.SchoolList.Count);
}
}
源码下载:
https://github.com/sunkaixuan/SqlSugar
.NET ORM框架 SqlSugar4.0 功能快速预览【开源】的更多相关文章
- .NET ORM框架 SqlSuagr4.0 功能详解与实践【开源】
SqlSugar 4.0 ORM框架的优势 为了未来能够更好的支持多库分布式的存储,并行计算等功能,将SqlSugar3.x全部重写,现有的架构可以轻松扩展多库. 源码下载: https://gith ...
- Webappbuilder开发快速预览
Webappbuilder开发快速预览 by 李远祥 Webappbuilder for ArcGIS 是由ArcGIS JavaScripit API和dojo创建的,它允许通过创建自己的widge ...
- C# 9.0 新特性预览 - 类型推导的 new
C# 9.0 新特性预览 - 类型推导的 new 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大 ...
- C# 9.0 新特性预览 - 空参数校验
C# 9.0 新特性预览 - 空参数校验 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它 ...
- C# 9.0 新特性预览 - 顶级语句
C# 9.0 新特性预览 - 顶级语句 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它们 ...
- C# 9.0 新特性预览 - init-only 属性
C# 9.0 新特性预览 - init-only 属性 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章 ...
- 【开源】OSharp3.0框架解说系列:新版本说明及新功能规划预览
OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...
- LitepalNewDemo【开源数据库ORM框架-LitePal2.0.0版本的使用】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo使用的是LitePal2.0.0版本,对于旧项目如何升级到2.0.0版本,请阅读<赶快使用LitePal 2.0版本 ...
- Android 7.0终极开发者预览版全攻略!
近日,Google的工程部副总裁Dave Burke在官方博客上正式发布开发者预览版5,此预览版是android 7.0 “牛轧糖”正式发布前最后一个预览版,同时也是在性能.功能上等多方面的表现上最接 ...
随机推荐
- monkey-----停止正在测试的monkey
第一步:adb shell ps | grep monkey:查找到正在测试的monkey包名 第二步:kill pid:删除查找出的monkey进程 以上完美的停止monkey测试
- Java开源生鲜电商平台-团购模块设计与架构(源码可下载)
Java开源生鲜电商平台-团购模块设计与架构(源码可下载) 说明:任何一个电商系统中,对于促销这块是必不可少的,毕竟这块是最吸引用户的,用户也是最爱的模块之一,理由很简单,便宜. 我的经验是无论是大的 ...
- 在ASP.NET Core中给上传图片功能添加水印
在传统的.NET框架中,我们给图片添加水印有的是通过HttpModules或者是HttpHandler,然后可以通过以下代码添加水印: var image = new WebImage(imageBy ...
- jdk源码阅读笔记-ArrayList
一.ArrayList概述 首先我们来说一下ArrayList是什么?它解决了什么问题?ArrayList其实是一个数组,但是有区别于一般的数组,它是一个可以动态改变大小的动态数组.ArrayList ...
- tcp套接字粘包解决办法
粘包只会出现在tcp,udp传输不会产生粘包现象.解决粘包的原理就是服务器预先向客户端发送客户端即将获取文件的大小. 第一版解决方案: 服务器: # Author : Kelvin # Date : ...
- GopherChina第一天小结
GopherChina第一天小结 今天参加了Asta举办的第五届GopherChina,第一天参加完,颇有感受,晚上回来趁着还有记忆,来做一下记录. 写在前面 一早从9点开始,一天下来一共八个主题,各 ...
- 【转】javascript笔记之apply、call、bind用法
原文地址:https://www.cnblogs.com/coco1s/p/4833199.html apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数 ...
- MySQL · 引擎特性 · InnoDB崩溃恢复
前言 数据库系统与文件系统最大的区别在于数据库能保证操作的原子性,一个操作要么不做要么都做,即使在数据库宕机的情况下,也不会出现操作一半的情况,这个就需要数据库的日志和一套完善的崩溃恢复机制来保证.本 ...
- traefik 结合 docker-compose 的快速安装及使用
traefik 介绍 traefik 是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理.负载均衡工具. 它支持多种后台 (Docker, Swarm, Kubernetes, Maratho ...
- 大数据与 AI 生态中的开源技术总结
本文由云+社区发表 作者:堵俊平 在数据爆炸与智能革命的新时代,新的平台与应用层出不穷,开源项目推动了前沿技术和业界生态快速发展.本次分享将以技术和生态两大视角来看大数据和人工智能技术的发展,通过分析 ...