蓝灯软件数据股份有限公司项目,代码开源。

SqlSugar是一款轻量级的MSSQL ORM ,除了具有媲美ADO的性能外还具有和EF相似简单易用的语法。

学习列表

  0、功能更新

 1、SqlSugar基础应用

 2、使用SqlSugar处理大数据

 3、使用SqlSugar实现Join  待更新

 4、使用SqlSugar实现分页+分组+多列排序 待更新

 5、节点故障如何进行主从调换

一、介简

优点:

1、优越的性能,查询使用  reflection.emit 创建IL语言+委托绑定 然后对该对象进行 cache ,datareader直接赋值给cache对象,高性能拉姆达解析,总体性能媲美 ADO.NET ,查询速度稍慢于datareader但稍快于datatable

2、大量语法糖,拉姆达表达示筛选,新颖的多表查询 ,方便的分页等

3、支持NOLOCK查询,提高性能

4、支持事务

5、内置实体类生成函数,无需使用第三方代码生成器

6、简单好用、例子齐全有问必答。

缺点:

目前只支持MSSQL,以后会全面发展 

组成:

sqlSugar是由sqlSugarClientr提供统一调用模式 ,sqlSugarClientr是由5个部分组成

1、自身函数 

2、实体生成

3、单表查询

4、多表查询

5、基类函数

如图:

 

二、使用教程

查询

 

1、单表或者单视图查询:

通过调用 db.Queryable() 的相关扩展函数 轻松搞定单表查询

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接

        {

                  

                   //查询所有

                    var student = db.Queryable<Student>().ToList();

                    //查询单条

                    var single = db.Queryable<Student>().Single(c => c.id == 1);

                    //取10-20条

                    var page1 = db.Queryable<Student>().Where(c => c.id > 10).OrderBy("id").Skip(10).Take(20).ToList();

                    //上一句的简化写法,同样取10-20条

                    var page2 = db.Queryable<Student>().Where(c => c.id > 10).OrderBy("id").ToPageList(2, 10);

                    //查询条数

                    var count = db.Queryable<Student>().Where(c => c.id > 10).Count();

                    //从第2条开始以后取所有

                    var skip = db.Queryable<Student>().Where(c => c.id > 10).OrderBy("id").Skip(2).ToList();

                    //取前2条

                    var take = db.Queryable<Student>().Where(c => c.id > 10).OrderBy("id").Take(2).ToList();

                    // Not like

                    var notLike = db.Queryable<Student>().Where(c => !c.name.Contains("a".ToString())).ToList();

                    // 可以在拉姆达使用 ToString和 Convert,比EF出色的地方

                    var convert1 = db.Queryable<Student>().Where(c => c.name == "a".ToString()).ToList();

                    var convert2 = db.Queryable<Student>().Where(c => c.id == Convert.ToInt32("1")).ToList();//

                    var convert3 = db.Queryable<Student>().Where(c => DateTime.Now > Convert.ToDateTime("2015-1-1")).ToList();

                    var convert4 = db.Queryable<Student>().Where(c => DateTime.Now > DateTime.Now).ToList();

                    //支持字符串Where 让你解决,更复杂的查询

                    var student12 = db.Queryable<Student>().Where(c => 1 == 1).Where("id>@id",new{id=1}).ToList();

 

  

1

2

3

//存在记录反回true,则否返回false

 bool isAny100 = db.Queryable<Student>().Any(c => c.id == 100);

 bool isAny1 = db.Queryable<Student>().Any(c => c.id == 1);

2、单表高级查询

根据条件查询并分页 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

/// <summary>

      /// 根据条件查询并且分页

      /// </summary>

      /// <param name="name"></param>

      /// <param name="sex"></param>

      /// <returns></returns>

      public static List<Student> GetStudent(string name, string sex, int pageIndex, int pageSize, string orderFileds,out int pageCount)

      {

          using (SqlSugarClient db = SugarDao.GetInstance())

          {

              var qable = db.Queryable<Student>();

              if (!string.IsNullOrEmpty(name))

              {

                  qable = qable.Where(it => it.name.Contains(name));

              }

              if (!string.IsNullOrEmpty(sex))

              {

                  qable = qable.Where(it => it.sex == sex);

              }

              if (!string.IsNullOrEmpty(orderFileds))//无需担心注入

              {

                  qable = qable.OrderBy(orderFileds);

              }

              pageCount = qable.Count();

              return qable.ToPageList(pageIndex, pageSize);

          }

      }

  

 新容器转换

1

2

3

4

5

6

7

public List<classNew> GetSelectList(int id)

{

    using (SugarDao db = new SugarDao())

    {

        return db.Queryable<Student>().Where(c=>c.id<10).Select(c => new classNew { newid = c.id, newname = c.name,xx_name=c.name }).ToList();//不支持匿名类转换,也不建议使用

    }

}

分组查询

1

2

3

4

5

6

7

public List<SexTotal> GetSexTotal()

       {

           using (SugarDao db = new SugarDao())

           {

               return db.Queryable<Student>().Where(c => c.id < 20).GroupBy("sex").Select<Student, SexTotal>("Sex,Count=count(*)").ToList();

           }

       }

1

SELECT Sex,Count=count(*)  FROM Student  WHERE 1=1  AND  (id < 20)    GROUP BY Sex --生成结果

  

  

 3、多表查询:

说到多表查询在众多ORM中无论是性能还是功能上都不满意,或者说还不如用SQL,下面是我的创意,放弃了强类型写法,让代码更接近SQL语句编写,让SQL完全可控,也解决了OMR多表的性能问题。

还有ORDERBY、GROUPBY和APPLY等,例子中就不介绍了。

拿EF来比较一下:

EF查询:

1

2

3

4

5

6

7

8

9

10

11

var reval = (from in db.Student

                               join sc in db.School on s.sch_id equals sc.id

                               join sb in db.Subject on s.id equals sb.sid

                               into ssb

                               from sb2 in ssb.DefaultIfEmpty()

                               select new {

                               s.id,

                               s.name,

                               s.sch_id,

                               s.sex

                               }).Where(c=>c.id>1).Where(c=>c.id>2).OrderBy(c=>c.id).ThenByDescending(c=>c.name).Skip(10).Take(10).ToList();

SqlSugar查询:

1

2

3

4

db.Sqlable().Form<Student>("s")

                  .Join<School> ("sc""sc.id""s.sch_id", JoinType.INNER)

                  .Join<subject>("sb""sb.sid""s.id", JoinType.LEFT).Where("s.id>@id1").Where("s.id>@id2")

                  .SelectToPageList<Models.Student>("s.*""s.id asc,s.name desc", 2, 10, new { id1=1,id2=2 });

更多的SqlSugar查询:

1

2

3

4

5

6

7

8

9

10

11

//表名是字符串写法

List<School> dataList = db.Sqlable()

   .Form("school""s")

   .Join("student""st""st.id""s.id", JoinType.INNER)

   .Join("student""st2""st2.id""st.id", JoinType.LEFT).Where("s.id>100 and s.id<@id").SelectToList<School>("st.*"new { id = 1 });

//多表分页

List<School> dataPageList = db.Sqlable()

    .Form<school>("s")

    .Join<student>("st""st.id""s.id", JoinType.INNER)

    .Join<student>("st2""st2.id""st.id", JoinType.LEFT).Where("s.id>100 and s.id<100").SelectToPageList<School>("st.*""s.id", 1, 10);

子查询加动态拼接

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

public List<Student> GetStudent(int id, string name)

       {

           int pageCount = 0;

           using (var db = SugarDao.GetInstance())

           {

               //Form("Student","s")语法优化成 Form<Student>("s")

               var sable = db.Sqlable().Form<Student>("s").Join<School>("l""s.sch_id""l.id", JoinType.INNER);

               if (!string.IsNullOrEmpty(name))

               {

                   sable = sable.Where("s.name=@name");

               }

               if (!string.IsNullOrEmpty(name))

               {

                   sable = sable.Where("s.id=@id or s.id=100");

               }

               if (id > 0) {

                   sable = sable.Where("l.id in (select top 10 id from school)");//where加子查询

               }

               //参数

               var pars = new { id = id, name = name };

               pageCount = sable.Count(pars);

               return sable.SelectToList<Student>("s.*", pars);

           }

       }

  

 4、 使用SQL或者存储过程查询:

 为了兼容上面满足不了的情况所以也写了这么个函数以便应急之需

  

1

2

3

4

5

6

7

8

9

10

var School = db.SqlQuery<School>("select * from School");

                    //获取id

                    var id = db.SqlQuery<int>("select top 1 id from School").Single();

                    //存储过程

                    //var spResult = db.SqlQuery<school>("exec sp_school @p1,@p2", new { p1=1,p2=2 });

                      

                    //无返回值

                    db.ExecuteCommand(sql);

  

添加

   

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接

{

            School s = new School()

            {

                name = "蓝翔"

            };

            //插入单条

            var id2 = Convert.ToInt32(db.Insert(s));

            //插入多条

            List<School> sList = new List<School>();

            sList.Add(s);

            var ids = db.InsertRange(sList);

 }

  

修改

  

1

2

3

4

//指定列更新

db.Update<School>(new { name = "蓝翔2" }, it => it.id == id);

//整个实体更新,注意主键必需为实体类的第一个属性

db.Update<School>(new School { id = id, name = "蓝翔2" }, it => it.id == id);

  

删除

1

2

3

4

5

6

7

db.Delete<School>(id);//注意主键必需为实体类的第一个属性

db.Delete<School>(it => it.id > 100);

db.Delete<School>(new string[] { "100""101""102" });

   

 db.FalseDelete<school>("is_del", 100);//假删除

 //等同于 update school set is_del=0 where id in(100)<br>

 db.FalseDelete<school>("is_del", it=>it.id==100);

更多底层函数

   

1

2

3

4

5

6

7

8

9

10

db.ExecuteCommand(sql);

 db.GetDataTable(sql);

 db.GetList<Student>(sql);

 db.GetSingle<Student>(sql + " where id=1");

 using (SqlDataReader read = db.GetReader(sql)) { }  //事务中一定要释放DataReader

 db.GetScalar(sql);

 db.GetString(sql);

 db.GetInt(sql);

  

实体生成

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接

 {

                  //根据当前数据库生成所有表的实体类文件 (参数:SqlSugarClient ,文件目录,命名空间)

                    db.ClassGenerating.CreateClassFiles(db,Server.MapPath("~/Models"),"Models");

                    //根据表名生成实体类文件

                    db.ClassGenerating.CreateClassFilesByTableNames(db, Server.MapPath("~/Models"), "Models" "student","school");

                    //根据表名生成class字符串

                    var str = db.ClassGenerating.TableNameToClass(db, "Student");

                    //根据SQL语句生成class字符串

                    var str2 = db.ClassGenerating.SqlToClass(db, "select top 1 * from Student""student");

  

事务

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接

{

   try{

       //开启事务,可以不使用事务,也可以使用多个事务

        db.BeginTran();

         

        //sq1

        //sql2

        //sql3

    }catch (Exception ex){

       //回滚事务

       db.RollbackTran();

       throw ex;

    }

}//关闭数据库连接

无锁查询

  当IsNoLock设为True时,查询生成的SQL语句表名的后面都会带有With(Nolock)

1

2

3

4

5

6

7

8

9

10

11

using (SqlSugarClient db = new SqlSugarClient(connStr))//开启数据库连接

{

          db.IsNoLock = true;

          //sql xxx with(nolock)

          db.IsNoLock = false;

          //sql xxx

          //sql xxx

          db.IsNoLock = true;

          //sql xxx with(nolock)

}//关闭数据库连接

  

 

支持多库切换的写法

定义一个sugarDao类来扩展SqlSugar

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

/// <summary>

  /// 扩展SqlSugarClient

  /// </summary>

  public class SugarDao

  {

      //禁止实例化

      private SugarDao() {

      }

      public static SqlSugarClient GetInstance()

      {

          string connection "Server=.;uid=sa;pwd=sasa;database=SqlSugarTest"; //这里可以动态根据cookies或session实现多库切换

          return new SqlSugarClient(connection);

      }

  }

  

使用无需传入connectionString

1

2

3

4

5

6

7

public School GetSingleSchool(int id)

  {

      using (SqlSugarClient db = SugarDao.GetInstance())

      {

          return db.Queryable<School>().Single(c => c.id == id);

      }

  }

  

 

三、性能测试:

             10000次

 

 1000次

10000次

.net4.52+EF 6.0+SQL12  以洗耻辱  

.NET Framework 4.52+ sql12 +EF6.0 ,EF性能明显上去了,就让它当个冠军吧,我也不去测试了,微软的东西升级后性能无需质疑,在多表查询和添删改方面综合下来也基本平手。

SqlSugar追求的是轻量、上手快、简单易用对SQL的可控性,也希望你能喜欢或者提出您宝贵意见。

 

V1.0源码下载地址:

SqlSugarDemo.rar_免费高速下载|百度网盘-分享无限制

V1.2源码下载地址:

sunkaixuan-SqlSugar-master.zip_免费高速下载|百度网盘-分享无限制

更改内容:

contains查询BUG,SQL拼接BUG

V1.3源码下载地址:

SqlSugar.rar_免费高速下载|百度网盘-分享无限制

更改内容:

添加 queryable/sqlable to dataTable  

CACHE BUG修复

支持  int?类型这类 nullable类型

此版本稳定,多家公司正在使用

有一点需要声名如果主键不是identity需要写成 insert(obj,false)这不是BUG

 主键位置在类中可以任意放无需放第一个

V1.5源码下载地址: 

SqlSugarV1.5.rar_免费高速下载|百度网盘-分享无限制

更改内容:

1、代码结构优化

2、删除语法需要注意 

 以前删除

 db.Delete<School>(new string[] { "100", "101", "102" });

需要改成下面这种写法

 db.Delete<School,string>(new string[] { "100", "101", "102" });

3、添加批量更新 

db.Update<School, string>(new { name = "蓝翔2" },new string []{"1","2"});

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐