花了一年时间完成的ORM框架,纯开源分享一下

杰拉尔 2016-12-11 10:57:02
SqlSugar ORM 支持 oracle sqlite mysql sqlServer 性能在Dapper之上

语句和EF差不多

SqlSugar 是一款小巧,并且功能齐全的ORM,并不需要像Dapper一样依赖第三方扩展

SqlSugar 语法易用简单 ,有漂亮的拉姆达语法,也支持Dapper SQL和ADO.NET(存储过程等)的所有功能

SqlSugar 性能达到原生水准,远超 Dapper和EF CORE。

SqlSugar 支持.NET CORE , 多个数据库

SqlSugar 体积小巧只有150K是EF的30分之1 ,NUGET直接可以下载

查询
//查询单条
var single = db.Queryable<Student>().Single(c => c.id == 1);
//查询单条根据主键
var singleByPk = db.Queryable<Student>().InSingle(1);
//查询单条没有记录返回空对象
var singleOrDefault = db.Queryable<Student>().SingleOrDefault(c => c.id == 11111111);
//查询单条没有记录返回空对象
var single2 = db.Queryable<Student>().Where(c => c.id == 1).SingleOrDefault();
//查询所有的Id
var singleFieldList = db.Queryable<Student>().Select<int>(it=>it.id).ToList();
//查询第一条
var first = db.Queryable<Student>().Where(c => c.id == 1).First();
var first2 = db.Queryable<Student>().Where(c => c.id == 1).FirstOrDefault();

//查询条数
var count = db.Queryable<Student>().Where(c => c.id > 10).Count();
//从第2条开始以后取所有
var skip = db.Queryable<Student>().Where(c => c.id > 10).OrderBy(it => it.id).Skip(2).ToList();
//取前2条
var take = db.Queryable<Student>().Where(c => c.id > 10).OrderBy(it => it.id).Take(2).ToList();
//Not like
string conval = "a";
var notLike = db.Queryable<Student>().Where(c => !c.name.Contains(conval.ToString())).ToList();
//Like
conval = "三";
var like = db.Queryable<Student>().Where(c => c.name.Contains(conval)).ToList();
//支持字符串Where 让你解决,更复杂的查询
var student12 = db.Queryable<Student>().Where(c => "a" == "a").Where("id>@id", new { id = 1 }).ToList();
var student13 = db.Queryable<Student>().Where(c => "a" == "a").Where("id>100 and id in( select 1)").ToList();

//存在记录反回true,则否返回false
bool isAny100 = db.Queryable<Student>().Any(c => c.id == 100);
bool isAny1 = db.Queryable<Student>().Any(c => c.id == 1);

//获取最大Id
object maxId = db.Queryable<Student>().Max(it => it.id);
int maxId1 = db.Queryable<Student>().Max(it => it.id).ObjToInt();//拉姆达
int maxId2 = db.Queryable<Student>().Max<int>("id"); //字符串写法
//获取最小
int minId1 = db.Queryable<Student>().Where(c => c.id > 0).Min(it => it.id).ObjToInt();//拉姆达
int minId2 = db.Queryable<Student>().Where(c => c.id > 0).Min<int>("id");//字符串写法


分页
int pageCount = 0;                
var page = db.Queryable<Student>().Where(c => c.id > 1).OrderBy(it => it.id).ToPageList(pageIndex,pageSize,ref pageCount);


多表操作
var jList = db.Queryable<Student>()
.JoinTable<School>((s1, s2) => s1.sch_id == s2.id) //默认left join
.Where<School>((s1, s2) => s1.id == 1)
.Select("s1.*,s2.name as schName")
.ToDynamic();


插入
插入单条
db.Insert(GetInsertItem()); //插入一条记录 (有主键也好,没主键也好,有自增列也好都可以插进去)


插入多条
db.InsertRange(GetInsertList()); //批量插入 支持(别名表等功能)
db.SqlBulkCopy(GetInsertList()); //批量插入 适合海量数据插入


设置不插入列
db.DisableInsertColumns = new string[] { "sex" };//sex列将不会插入值
Student s = new Student()
{
name = "张" + new Random().Next(1, int.MaxValue),
sex = "gril"
};var id = db.Insert(s); //插入
//查询刚插入的sex是否有值
var sex = db.Queryable<Student>().Single(it => it.id == id.ObjToInt()).sex;//无值
var name = db.Queryable<Student>().Single(it => it.id == id.ObjToInt()).name;//有值

//SqlBulkCopy同样支持不插入列设置
db.SqlBulkCopy(GetInsertList());

//清空禁止插入列
db.DisableInsertColumns = null;
//添加禁止插入列
db.AddDisableInsertColumns("name","id
");

插入或者更新 NEW
当主键值为 0 、sttring.Empty、NULL 或者 Guid.Empty时执行插操作,否则执行更新
db.AddDisableInsertColumns("UpdateTime");//禁止插入更新时间
db.AddDisableUpdateColumns("CreateTime");//禁止更新创建时间
db.InsertOrUpdate(GetInsertItem2());


删除


更新
指定列更新
db.Update<School>(new { name = "蓝翔14" }, it => it.id == 14); //只更新name列 条件 id=14
db.Update<School, int>(new { name = "蓝翔11 23 12", areaId = 2 }, 11, 23, 12);//更新name和areaId 根据主键
db.Update<School, string>(new { name = "蓝翔2" }, new string[] { "11", "21" });
db.Update<School>(new { name = "蓝翔2" }, it => it.id == 100);
var array=new int[]{1,2,3};
db.Update<School>(new { name = "蓝翔2" }, it => array.Contains(it.id));// id in 1,2,3

使用字典更新
var dic = new Dictionary<string, string>();
dic.Add("name", "第十三条");
dic.Add("areaId", "1");
db.Update<School, int>(dic, 13);

整个实体更新
db.Update(new School { id = 16, name = "蓝翔16", AreaId = 1 });
db.Update<School>(new School { id = 12, name = "蓝翔12", AreaId = 2 }, it => it.id == 18);
db.Update<School>(new School() { id = 11, name = "青鸟11" });
与指定列更新不同的是只要实体中有的字段都会更新,如果想不更新指定字段请用排除更新列

设置不更新列
db.DisableUpdateColumns = new string[] { "CreateTime" };//设置CreateTime不更新TestUpdateColumns updObj = new TestUpdateColumns()
{
VGUID = Guid.Parse("542b5a27-6984-47c7-a8ee-359e483c8470"),
Name = "xx",
Name2 = "xx2",
IdentityField = 0,
CreateTime = null
};
//CreateTime将不会被更新
db.Update(updObj);
//以前实现这种更新需要用指定列的方式实现,现在就简单多了。
//批量更新 数据量小时建议使用
var updateResult = db.UpdateRange(GetUpdateList());
//批量更新 数据量大时建议使用
var updateResult2 = db.SqlBulkReplace(GetUpdateList2());

//更新字符串
db.Update<Student>("sch_id=sch_id+1", it => it.id == 1);

//清空禁止更新列
db.DisableUpdateColumns = null;
//新语法添加禁止更新列
db.AddDisableUpdateColumn("id", "name");//添加禁止更新列


技术交流群:225982985
...全文
8327 60 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
60 条回复
切换为时间正序
请发表友善的回复…
发表回复
边城° 2020-09-23
  • 打赏
  • 举报
回复
牛啊,大佬,我才刚出校门
mokya 2018-08-02
  • 打赏
  • 举报
回复
我使用手机粗略看原文和评论的。我想请教作者。能够用xml保存sql语句,实现持久化吗?感谢。
  • 打赏
  • 举报
回复
您评论的那个js 将HTML 导出 Excel怎么用呢
肆风 2018-04-02
  • 打赏
  • 举报
回复
看介绍很厉害。
linlurui 2017-08-25
  • 打赏
  • 举报
回复
跟我做的那个很像,不过我只花了一个月时间,先是发到了codeplex,现在转到码云了,叫dapperQ,是基于dapper反射实体的linq的实现
ChinaBruceHe 2017-08-22
  • 打赏
  • 举报
回复
楼主参考的LINQTODB?
潜浮生 2017-08-18
  • 打赏
  • 举报
回复
con.Queryable().Where(qq =>list.Contais(qq.ID??0));这种不识别??符号的情况,不知道博主有没有遇到过
xiaoxiaotank 2017-02-10
  • 打赏
  • 举报
回复
如果性能就跟楼主所说的在dapper之上,那完全是个好工具
sh521 2016-12-23
  • 打赏
  • 举报
回复
过来瞻仰大神!~
SinGooCMS 2016-12-23
  • 打赏
  • 举报
回复
大概看了下,感觉还行吧!不过我还是喜欢NHibrate那样有映射表的ORM,它是写在外面 的,后来我整合到里面了!
笑容融化坚冰 2016-12-20
  • 打赏
  • 举报
回复
高手,顶一下。
brucel51 2016-12-20
  • 打赏
  • 举报
回复
把所有的sql字符串换成表达式树,就更完美了。
baidu_27549073 2016-12-19
  • 打赏
  • 举报
回复
评论真是精彩,我对楼主是佩服的。但是微软的东西我还没学会,实在是无力去学习新的东西了,毕竟微软的东西更新比较稳定,从长远来讲,学习楼主的东西有点得不偿失。
baij1230 2016-12-18
  • 打赏
  • 举报
回复
谢谢分享,楼主好人。长知识了
杰拉尔 2016-12-16
  • 打赏
  • 举报
回复
引用 48 楼 daixf_csdn 的回复:
[quote=引用 47 楼 jhl52771 的回复:] [quote=引用 46 楼 daixf_csdn 的回复:] [quote=引用 41 楼 jhl52771 的回复:] [quote=引用 40 楼 daixf_csdn 的回复:] linq to ef无法很方便的实现 or 条件的动态拼接,这个能实现不?
最好是举个例子,EF除了字符串拼接不支持外, IF来判段 显示不同的 .Where 内容 完全可以变相的满你的需求。 在这方面和EF功能还是一样的, 比如动态字段排序 .orderBy(字符串变量) 这些我是比EF方便的 [/quote] 比如这种代码,拼sql的,条件是不确定的,然后有多个where条件组成链条。这种写法下,多个where条件之间是and关系。 不容易做到or关系。
string moduleName = queryCondition.GetType().Name;
                switch (moduleName)
                {
                    case "ba_itemQueryModel":
                        #region 按条件查询
                        var condition = queryCondition as ba_itemQueryModel;

                        //拼接查询条件
                        if (!condition.ItemCode.IsNullOrEmpty())
                        {
                            query = query.Where(c => c.ItemCode.Contains(condition.ItemCode));
                        }

                        if (!condition.GoodsCode.IsNullOrEmpty())
                        {
                            query = query.Where(c => c.GoodsCode.Contains(condition.GoodsCode));
                        }

                        if (condition.Status != "All")
                        {
                            query = query.Where(c => c.Status == condition.Status);
                        }

                        if (!condition.WideSearch.IsNullOrEmpty())
                        {
                            List<string> list = condition.WideSearch.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).ToList();
                            query = from q in query
                                    join g in context.ba_goods on q.GoodsCode equals g.GoodsCode
                                    where list.All(c => q.Description.Contains(c)) || list.All(c => g.Description.Contains(c))
                                    || list.All(c => g.Properties.Contains(c)) || list.All(c => q.OperUser == c)
                                    select q;
                        }
                        break;
                        #endregion
                    default:
                        throw new CustomException(string.Format("系统不支持的查询模型{0}!", moduleName));
                }
[/quote] 首先你的解决问题的方法是不对的, OR在SQL里面没有 AND 或者 WHERE 是不能直接写的 也就是说 Where id=1 or id=2 相当于 Where(id=1 or id=2)相当于LINQ where(it=>it.id=1||it.id==2) OR只是AND或者WHERE中的一个成员, 在EF中 将SQL中的AND和WHERE都统称为 WHERE。 所以你认为不方便是你的想法违背SQL本意,换种思路就可以实现你需要的功能。[/quote] 这个,我当然是知道的。 比如,如果能提供query.Or()方法,那不是挺好的?[/quote] query.where().or().where() 这样写代码会很乱,没有办法用语法实现 OR外面的(),所以微软也就只能这么设计EF。
圣殿骑士18 2016-12-16
  • 打赏
  • 举报
回复
引用 47 楼 jhl52771 的回复:
[quote=引用 46 楼 daixf_csdn 的回复:] [quote=引用 41 楼 jhl52771 的回复:] [quote=引用 40 楼 daixf_csdn 的回复:] linq to ef无法很方便的实现 or 条件的动态拼接,这个能实现不?
最好是举个例子,EF除了字符串拼接不支持外, IF来判段 显示不同的 .Where 内容 完全可以变相的满你的需求。 在这方面和EF功能还是一样的, 比如动态字段排序 .orderBy(字符串变量) 这些我是比EF方便的 [/quote] 比如这种代码,拼sql的,条件是不确定的,然后有多个where条件组成链条。这种写法下,多个where条件之间是and关系。 不容易做到or关系。
string moduleName = queryCondition.GetType().Name;
                switch (moduleName)
                {
                    case "ba_itemQueryModel":
                        #region 按条件查询
                        var condition = queryCondition as ba_itemQueryModel;

                        //拼接查询条件
                        if (!condition.ItemCode.IsNullOrEmpty())
                        {
                            query = query.Where(c => c.ItemCode.Contains(condition.ItemCode));
                        }

                        if (!condition.GoodsCode.IsNullOrEmpty())
                        {
                            query = query.Where(c => c.GoodsCode.Contains(condition.GoodsCode));
                        }

                        if (condition.Status != "All")
                        {
                            query = query.Where(c => c.Status == condition.Status);
                        }

                        if (!condition.WideSearch.IsNullOrEmpty())
                        {
                            List<string> list = condition.WideSearch.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).ToList();
                            query = from q in query
                                    join g in context.ba_goods on q.GoodsCode equals g.GoodsCode
                                    where list.All(c => q.Description.Contains(c)) || list.All(c => g.Description.Contains(c))
                                    || list.All(c => g.Properties.Contains(c)) || list.All(c => q.OperUser == c)
                                    select q;
                        }
                        break;
                        #endregion
                    default:
                        throw new CustomException(string.Format("系统不支持的查询模型{0}!", moduleName));
                }
[/quote] 首先你的解决问题的方法是不对的, OR在SQL里面没有 AND 或者 WHERE 是不能直接写的 也就是说 Where id=1 or id=2 相当于 Where(id=1 or id=2)相当于LINQ where(it=>it.id=1||it.id==2) OR只是AND或者WHERE中的一个成员, 在EF中 将SQL中的AND和WHERE都统称为 WHERE。 所以你认为不方便是你的想法违背SQL本意,换种思路就可以实现你需要的功能。[/quote] 这个,我当然是知道的。 比如,如果能提供query.Or()方法,那不是挺好的?
杰拉尔 2016-12-16
  • 打赏
  • 举报
回复
引用 46 楼 daixf_csdn 的回复:
[quote=引用 41 楼 jhl52771 的回复:] [quote=引用 40 楼 daixf_csdn 的回复:] linq to ef无法很方便的实现 or 条件的动态拼接,这个能实现不?
最好是举个例子,EF除了字符串拼接不支持外, IF来判段 显示不同的 .Where 内容 完全可以变相的满你的需求。 在这方面和EF功能还是一样的, 比如动态字段排序 .orderBy(字符串变量) 这些我是比EF方便的 [/quote] 比如这种代码,拼sql的,条件是不确定的,然后有多个where条件组成链条。这种写法下,多个where条件之间是and关系。 不容易做到or关系。
string moduleName = queryCondition.GetType().Name;
                switch (moduleName)
                {
                    case "ba_itemQueryModel":
                        #region 按条件查询
                        var condition = queryCondition as ba_itemQueryModel;

                        //拼接查询条件
                        if (!condition.ItemCode.IsNullOrEmpty())
                        {
                            query = query.Where(c => c.ItemCode.Contains(condition.ItemCode));
                        }

                        if (!condition.GoodsCode.IsNullOrEmpty())
                        {
                            query = query.Where(c => c.GoodsCode.Contains(condition.GoodsCode));
                        }

                        if (condition.Status != "All")
                        {
                            query = query.Where(c => c.Status == condition.Status);
                        }

                        if (!condition.WideSearch.IsNullOrEmpty())
                        {
                            List<string> list = condition.WideSearch.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).ToList();
                            query = from q in query
                                    join g in context.ba_goods on q.GoodsCode equals g.GoodsCode
                                    where list.All(c => q.Description.Contains(c)) || list.All(c => g.Description.Contains(c))
                                    || list.All(c => g.Properties.Contains(c)) || list.All(c => q.OperUser == c)
                                    select q;
                        }
                        break;
                        #endregion
                    default:
                        throw new CustomException(string.Format("系统不支持的查询模型{0}!", moduleName));
                }
[/quote] 首先你的解决问题的方法是不对的, OR在SQL里面没有 AND 或者 WHERE 是不能直接写的 也就是说 Where id=1 or id=2 相当于 Where(id=1 or id=2)相当于LINQ where(it=>it.id=1||it.id==2) OR只是AND或者WHERE中的一个成员, 在EF中 将SQL中的AND和WHERE都统称为 WHERE。 所以你认为不方便是你的想法违背SQL本意,换种思路就可以实现你需要的功能。
圣殿骑士18 2016-12-16
  • 打赏
  • 举报
回复
引用 41 楼 jhl52771 的回复:
[quote=引用 40 楼 daixf_csdn 的回复:] linq to ef无法很方便的实现 or 条件的动态拼接,这个能实现不?
最好是举个例子,EF除了字符串拼接不支持外, IF来判段 显示不同的 .Where 内容 完全可以变相的满你的需求。 在这方面和EF功能还是一样的, 比如动态字段排序 .orderBy(字符串变量) 这些我是比EF方便的 [/quote] 比如这种代码,拼sql的,条件是不确定的,然后有多个where条件组成链条。这种写法下,多个where条件之间是and关系。 不容易做到or关系。
string moduleName = queryCondition.GetType().Name;
                switch (moduleName)
                {
                    case "ba_itemQueryModel":
                        #region 按条件查询
                        var condition = queryCondition as ba_itemQueryModel;

                        //拼接查询条件
                        if (!condition.ItemCode.IsNullOrEmpty())
                        {
                            query = query.Where(c => c.ItemCode.Contains(condition.ItemCode));
                        }

                        if (!condition.GoodsCode.IsNullOrEmpty())
                        {
                            query = query.Where(c => c.GoodsCode.Contains(condition.GoodsCode));
                        }

                        if (condition.Status != "All")
                        {
                            query = query.Where(c => c.Status == condition.Status);
                        }

                        if (!condition.WideSearch.IsNullOrEmpty())
                        {
                            List<string> list = condition.WideSearch.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).ToList();
                            query = from q in query
                                    join g in context.ba_goods on q.GoodsCode equals g.GoodsCode
                                    where list.All(c => q.Description.Contains(c)) || list.All(c => g.Description.Contains(c))
                                    || list.All(c => g.Properties.Contains(c)) || list.All(c => q.OperUser == c)
                                    select q;
                        }
                        break;
                        #endregion
                    default:
                        throw new CustomException(string.Format("系统不支持的查询模型{0}!", moduleName));
                }
杰拉尔 2016-12-15
  • 打赏
  • 举报
回复
引用 40 楼 daixf_csdn 的回复:
linq to ef无法很方便的实现 or 条件的动态拼接,这个能实现不?
最好是举个例子,EF除了字符串拼接不支持外, IF来判段 显示不同的 .Where 内容 完全可以变相的满你的需求。 在这方面和EF功能还是一样的, 比如动态字段排序 .orderBy(字符串变量) 这些我是比EF方便的
圣殿骑士18 2016-12-15
  • 打赏
  • 举报
回复
linq to ef无法很方便的实现 or 条件的动态拼接,这个能实现不?
加载更多回复(40)

62,243

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧