http://www.cnblogs.com/sunkaixuan/p/5911334.html
1、前言/Preface
SqlSugar从去年到现在已经一年了,版本从1.0升到了现在的2.8 ,这是一个稳定版本 ,有数家公司已经项目上线,在这里我将SqlSugar的功能重新整理成一篇新的贴子,希望大家喜欢。
公司团队项目、产品已经完全抛弃EF,SqlSugar定位不是ORM,而是为了方便的让你去写Sql。
媲美原生ADO.NET的性能、简洁的语法和支持Json 、Dynamic、 List<T>、 List<string[]>、 ValueType和 Dictionary 等多种类型的返回值 有很多亮点。
GitHub下载地址:
MSSQL .NET 4.0+
https://github.com/sunkaixuan/SqlSugar
MSSQL .NET Core 版本
https://github.com/sunkaixuan/ASP_NET_CORE_ORM_SqlSugar
Sqlite .net4.0+
https://github.com/sunkaixuan/SqliteSugar
MYSQL .NET 4.0+
http://www.cnblogs.com/sunkaixuan/p/5747259.html
ORACLE.NET 4.0+
https://github.com/sunkaixuan/OracleSugar
ORACLE CORE ,MYSQL CORE,SQLITE CORE 待开发
最新更新:
3.0.02
可以设置生成实体的摘要
var temSummary = ClassTemplate.ClassFieldSummaryTemplate;
批量添加别名表功能
//批量设置别名表 //db.ClassGenerating.ForeachTables(db, tableName => //{ // db.AddMappingTable(new KeyValue() { Key = tableName.Replace("bbs.",""), Value = tableName }); //key实体名,value表名 //});
别名列功能
using System; using System.Collections.Generic; using System.Linq; using System.Text; using NewTest.Dao; using System.Data.SqlClient; using SqlSugar; namespace NewTest.Demos { //别名列的功能 public class MappingColumns : IDemos { public void Init() { Console.WriteLine("启动MappingColumns.Init"); //全局设置 using (var db = SugarFactory.GetInstance()) { var list = db.Queryable<Student>().Where(it=>it.classId==1).ToList(); } } public class Student { //id public int classId { get; set; } //name public string className { get; set; } //sch_id public int classSchoolId { get; set; } public int isOk { get; set; } } /// <summary> /// 全局配置别名列(不区分表) /// </summary> public class SugarConfigs { //key实体字段名 value表字段名 ,KEY唯一否则异常 public static List<KeyValue> MpList = new List<KeyValue>(){ new KeyValue(){ Key="classId", Value="id"}, new KeyValue(){ Key="className", Value="name"}, new KeyValue(){ Key="classSchoolId", Value="sch_id"} }; } /// <summary> /// SqlSugar实例工厂 /// </summary> public class SugarFactory { //禁止实例化 private SugarFactory() { } public static SqlSugarClient GetInstance() { string connection = SugarDao.ConnectionString; //这里可以动态根据cookies或session实现多库切换 var db = new SqlSugarClient(connection); //注意:只有启动属性映射才可以使用SetMappingColumns db.IsEnableAttributeMapping = true; db.SetMappingColumns(SugarConfigs.MpList);//设置关联列 (引用地址赋值,每次赋值都只是存储一个内存地址) return db; } } } }
通过属性设置别名表和别名列和字段过滤
using System; using System.Collections.Generic; using System.Linq; using System.Text; using NewTest.Dao; using Models; using System.Data.SqlClient; using SqlSugar; namespace NewTest.Demos { //通过属性的方法设置别名表和别名字段(主键和自添列都无需设置 SQLSUGAR会帮你自动处理) //注意:【属性映射和 (SetMappingTables、SetMappingColumns)方式映射 2种选其中一,不清楚底层缓存机质不建议同时使用】 public class AttributesMapping : IDemos { public void Init() { Console.WriteLine("启动AttributesMapping.Init"); using (var db = DBManager.GetInstance()) { //查询 var list = db.Queryable<TestStudent>() .Where(it => it.className.Contains("小")).OrderBy(it => it.classSchoolId).Select<V_Student>(it => new V_Student() { id = it.classId, name = it.className }).ToList(); var list2 = db.Queryable<TestStudent>() .JoinTable<TestSchool>((s1, s2) => s1.classSchoolId == s2.classId) .OrderBy<TestSchool>((s1, s2) => s1.classId) .Select<TestStudent, TestSchool, V_Student>((s1, s2) => new V_Student() { id = s1.classId, name = s1.className, SchoolName = s2.className }).ToList(); //添加 TestStudent s = new TestStudent(); s.className = "属性名"; s.classSchoolId = 1; var id = db.Insert(s); s.classId = id.ObjToInt(); //更新 db.Update(s); db.Update<TestStudent, int>(s, 100); db.Update<TestStudent>(s, it => it.classId == 100); db.SqlBulkReplace(new List<TestStudent>() { s }); //删除 db.Delete<TestStudent>(it => it.classId == 100); } } /// <summary> /// 属性只作为初始化映射,SetMappingTables和SetMappingColumns可以覆盖 /// </summary> [SugarMapping(TableName = "Student")] public class TestStudent { [SugarMapping(ColumnName = "id")] public int classId { get; set; } [SugarMapping(ColumnName = "name")] public string className { get; set; } [SugarMapping(ColumnName = "sch_id")] public int classSchoolId { get; set; } public int isOk { get; set; } /// <summary> /// 数据库并没有这一列 /// </summary> public string errorField { get; set; } } [SugarMapping(TableName = "School")] public class TestSchool { [SugarMapping(ColumnName = "id")] public int classId { get; set; } [SugarMapping(ColumnName = "name")] public string className { get; set; } public int AreaId = 1; } } public class DBManager { public static SqlSugarClient GetInstance() { var db = new SqlSugarClient(SugarDao.ConnectionString); db.IsEnableAttributeMapping = true;//启用属性映射 db.IsIgnoreErrorColumns = true;//忽略非数据库列 db.IsEnableLogEvent = true;//启用日志事件 db.LogEventStarting = (sql, par) => { Console.WriteLine(sql + " " + par + "\r\n"); }; return db; } } }
拉姆达支持了 contains
db.Update<School>(new { name = "蓝翔2" }, it => array.Contains(it.id))
添加了高性能批量更新
db.SqlBulkReplace
2.9.1.0
添加了SQL日志和监控功能
using System; using System.Collections.Generic; using System.Linq; using System.Text; using NewTest.Dao; using Models; using System.Data.SqlClient; using SqlSugar; namespace NewTest.Demos { //日志记录功能 public class Log : IDemos { public void Init() { Console.WriteLine("启动Log.Init"); using (var db = SugarDemoDao.GetInstance()) { var a1 = db.Queryable<Student>().Where(it => it.id == 1).ToList(); var a2 = db.Queryable<Student>().OrderBy(it => it.id).ToList(); } } public class SugarConfigs { public static Action<string, string> LogEventStarting = (sql, pars) => { Console.WriteLine("starting:" + sql + " " + pars); using (var db = SugarDemoDao.GetInstance()) { //日志记录件事件里面用到数据库操作 IsEnableLogEvent一定要为false否则将引起死循环,并且要新开一个数据实例 像我这样写就没问题。 db.IsEnableLogEvent = false; db.ExecuteCommand("select 1"); } }; public static Action<string, string> LogEventCompleted = (sql, pars) => { Console.WriteLine("completed:" + sql + " " + pars); }; } /// <summary> /// SqlSugar /// </summary> public class SugarDemoDao { public static SqlSugarClient GetInstance() { var db = new SqlSugarClient(SugarDao.ConnectionString); db.IsEnableLogEvent = true;//启用日志事件 db.LogEventStarting = SugarConfigs.LogEventStarting; db.LogEventCompleted = SugarConfigs.LogEventCompleted; return db; } } } }
大量语法优化
以前 .select<oldT,newT>(it=>newT{ id=it.id})可以写成.select<newT>(it=>newT{ id=it.id})
以前 .select<T,int>(it=>it.id)可以写成.select<int>(it=>it.id);
Join也进行了美化可以不用写第一个T
//2表关联查询 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(); /*等于同于 SELECT s1.*,s2.name as schName FROM [Student] s1 LEFT JOIN [School] s2 ON s1.sch_id = s2.id WHERE s1.id = 1 */ //2表关联查询并分页 var jList2 = db.Queryable<Student>() .JoinTable<School>((s1, s2) => s1.sch_id == s2.id) //默认left join //如果要用inner join这么写 //.JoinTable<School>((s1, s2) => s1.sch_id == s2.id ,JoinType.INNER) .Where<School>((s1, s2) => s1.id > 1) .OrderBy(s1 => s1.name) .Skip(10) .Take(20) .Select("s1.*,s2.name as schName") .ToDynamic(); //3表查询并分页 var jList3 = db.Queryable<Student>() .JoinTable<School>((s1, s2) => s1.sch_id == s2.id) // left join School s2 on s1.id=s2.id .JoinTable<School>((s1, s3) => s1.sch_id == s3.id) // left join School s3 on s1.id=s3.id .Where<School>((s1, s2) => s1.id > 1) // where s1.id>1 .Where(s1 => s1.id > 0) .OrderBy<School>((s1, s2) => s1.id) //order by s1.id 多个order可以 .oderBy().orderby 叠加 .Skip(10) .Take(20) .Select("s1.*,s2.name as schName,s3.name as schName2")//select目前只支持这种写法 .ToDynamic(); //上面的方式都是与第一张表join,第三张表想与第二张表join写法如下 List<V_Student> jList4 = db.Queryable<Student>() .JoinTable<School>((s1, s2) => s1.sch_id == s2.id) // left join School s2 on s1.id=s2.id .JoinTable<School, Area>((s1, s2, a1) => a1.id == s2.AreaId)// left join Area a1 on a1.id=s2.AreaId 第三张表与第二张表关联 .JoinTable<Area, School>((s1, a1, s3) => a1.id == s3.AreaId)// left join School s3 on a1.id=s3.AreaId 第四第表第三张表关联 .JoinTable<School>((s1, s4) => s1.sch_id == s4.id) // left join School s2 on s1.id=s4.id .Select<School, Area, V_Student>((s1, s2, a1) => new V_Student { id = s1.id, name = s1.name, SchoolName = s2.name, AreaName = a1.name }).ToList();
2.8.01设置不插入列
2.8.0.0 强化了 SELECT 新容器转换功能,以前只能 id=it.id 这种等值操作,现在支持了类型转换函数,另外还支持了外部传参和内部硬编码的写法
//新容器转换函数的支持,例子外其它写法暂不支持 var f1 = db.Queryable<InsertTest>().Select<InsertTest, Student>(it => new Student() { name = it.d1.ObjToString(), id = it.int1.ObjToInt() // 支持ObjToXXX 所有函数 }).ToList(); var f2 = db.Queryable<InsertTest>().Select<InsertTest, Student>(it => new Student() { name = Convert.ToString(it.d1),//支持Convet.ToXX所有函数 id = it.int1.ObjToInt(), sex = Convert.ToString(it.d1), }).ToList(); var f3 = db.Queryable<InsertTest>() .JoinTable<InsertTest, InsertTest>((i1, i2) => i1.id == i2.id) .Select<InsertTest, InsertTest, Student>((i1, i2) => new Student() { name = Convert.ToString( i1.d1), //多表查询例子 id = i1.int1.ObjToInt( ), sex = Convert.ToString( i2.d1 ), }).ToList(); //Select 外部参数用法 var f4 = db.Queryable<InsertTest>().Where("1=1", new { id = id + 100 }).Select<InsertTest, Student>(it => new Student() { id = "@id".ObjToInt(), //取的是 id+100 的值 name = "张三",//内部参数可以直接写 sex = it.txt, sch_id=it.id }).ToList(); var f6 = db.Queryable<InsertTest>() .JoinTable<InsertTest, InsertTest>((i1, i2) => i1.id == i2.id) .Where("1=1", new { id = 100, name = "张三",isOk=true }) //外部传参给@id .Select<InsertTest, InsertTest, Student>((i1, i2) => new Student() { name = "@name".ObjToString(), //多表查询例子 id = "@id".ObjToInt(), sex = i2.txt, sch_id = 1, isOk = "@isOk".ObjToBool() }).ToList();
2.7.1.3 更新了SqlSugar所有的函数的备注、类的备注
OracleSugar已经上传NUGET GIT文章最下方有地址
2.7.08 支持了字典参数
List<Student> list2 = db.SqlQuery<Student>("select * from Student where id=@id", new { id = 1 }); 其中new { id = 1 }可以改成 Dictionary<string, object>(){{id,1}}
db.Update<School>(new { name = "蓝翔14" }, it => it.id == 14); 其中 new { name = "蓝翔14" } 可以改成 Dictionary<string, object>(){{name,"蓝翔14"}}
这样做有什么好处呢?动态权限的时候弱类型会比较好处理
2.7.1.0 JoinTable支持了字符串,可以做更复杂的查询例如:
using (SqlSugarClient db = SugarDao.GetInstance()) { var childQuery = db.Queryable<Area>().Where("id=@id").Select(it => new { id=it.id }).ToSql();//创建子查询SQL string childTableName=string.Format("({0})",childQuery.Key);//将SQL语句用()包成表 var queryable = db.Queryable<Student>() .JoinTable<Student, School>((s1, s2) => s1.sch_id == s2.id) .JoinTable(childTableName, "a1", "a1.id=s2.areaid", new { id = 1 }, JoinType.INNER) .OrderBy(s1 => s1.id); //SELECT * FROM ( //SELECT newid = s1.id, studentName = s1.name, schoolName = s2.name, areaName = a1.name ,row_index=ROW_NUMBER() OVER(ORDER BY s1.id ASC ) FROM [Student] s1 //LEFT JOIN School s2 ON ( s1.sch_id = s2.id ) //INNER JOIN (SELECT * FROM [Area] WHERE 1=1 AND id=@id ) a1 ON a1.id=s2.areaid WHERE 1=1 // //) t WHERE t.row_index BETWEEN 1 AND 200 var list= queryable.Select<Student, School, Area, classNew>((s1, s2, a1) => new classNew { newid = s1.id, studentName = s1.name, schoolName = s2.name, areaName = a1.name }) .ToPageList(0,200); var count=queryable.Count(); }