SqlSugar在查詢的功能是很是強大的,多表查詢、分頁查詢 、 一對一查詢、二級緩存、一對多查、WhenCase等複雜函數、Mapper功能、和拉姆達自定義擴展等,用好了是能夠作到真正零SQL的一款ORM。html
首先將SqlSugar更新到4.8版本,下面我就來一一講解每種查詢的寫法git
public class DbContext { public DbContext() { Db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = "server=.;uid=sa;pwd=sasa;database=SqlSugar4XTest", DbType = DbType.SqlServer, IsAutoCloseConnection = true,//開啓自動釋放模式和EF原理同樣我就很少解釋了 //InitKey默認SystemTable }); } public SqlSugarClient Db;//用來處理事務多表查詢和複雜的操做 public SimpleClient<Student> StudentDb { get { return new SimpleClient<Student>(Db); } }//用來處理Student表的經常使用操做 public SimpleClient<School> SchoolDb { get { return new SimpleClient<School>(Db); } }//用來處理School表的經常使用操做 }
咱們使用的SimpleClient實現了簡單的單表查詢,如何擴展SimpleClient能夠看個人上一篇文章github
//調式代碼 用來打印SQL Db.Aop.OnLogExecuting = (sql, pars) => { Console.WriteLine(sql + "\r\n" + Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value))); Console.WriteLine(); }; var data1 = StudentDb.GetById(1);//根據ID查詢 var data2 = StudentDb.GetList();//查詢全部 var data3 = StudentDb.GetList(it => it.Id == 1); //根據條件查詢 var p = new PageModel() { PageIndex=1,PageSize=2};// 分頁查詢 var data4 = StudentDb.GetPageList(it => it.Name == "xx", p); Console.Write(p.PageCount);//返回總數 // 分頁查詢加排序 var data5 = StudentDb.GetPageList(it => it.Name == "xx", p,it=>it.Name,OrderByType.Asc); Console.Write(p.PageCount);//返回總數
對於Grid控件來講我通常用這個表單封裝好了所有通用sql
List<IConditionalModel> conModels = new List<IConditionalModel>(); conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.Equal, FieldValue = "1" });//id=1 conModels.Add(new ConditionalModel() { FieldName = "Student.id", ConditionalType = ConditionalType.Equal, FieldValue = "1" });//id=1 conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.Like, FieldValue = "1" });// id like '%1%' conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.IsNullOrEmpty }); conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.In, FieldValue = "1,2,3" }); conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.NotIn, FieldValue = "1,2,3" }); conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.NoEqual, FieldValue = "1,2,3" }); conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.IsNot, FieldValue = null });// id is not null var data6 = StudentDb.GetPageList(conModels,p,it=>it.Name,OrderByType.Asc); //組裝條件當查詢條件的 分頁查詢加排序
基本上和EF差不太多緩存
var data3 = StudentDb.GetList(it => it.Name.Contains("a")); // like %a% 模糊查詢 var p2 = new int[] { 1, 2, 3 }; var data31 = StudentDb.GetList(it => p2.Contains(it.Id)); // id in (1,2,3)
咱們還支持了SqlFunc.xxx一串方法來給咱們使用,以下用法app
var data311 = StudentDb.GetList(it => SqlFunc.Between(it.Id,1,2)); // id between 1 and 2
var exp = Expressionable.Create<Student>() .OrIF(1 == 1, it => it.Id == 11) .And(it => it.Id == 1) .AndIF(2 == 2, it => it.Id == 1) .Or(it => it.Name == "a1").ToExpression();//拼接表達式 var data311 = StudentDb.GetList(exp); // 動態表達式查詢
例如咱們有自定義的SQL函數或者SqlSugar不支持的咱們能夠自定擴展函數
具體看這個鏈接 http://www.codeisbug.com/Doc/8/1162性能
咱們上面看到的簡單查詢底層都是用複雜查詢實現的ui
var data1 = StudentDb.GetById(1); //等同於 var data2 = Db.Queryable<Student>().Single(it => it.Id == 1);
var list = Db.Queryable<Student, School>((st, sc) => new object[] { JoinType.Left,st.SchoolId==sc.Id}) .Select((st,sc)=>new{Id=st.Id,Name=st.Name,SchoolName=sc.Name}).ToList();
生成的SQL以下spa
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])
var s11 = Db.Queryable<Student, School>((st, sc) => st.SchoolId == sc.Id) .Select<ViewModelStudent3>().ToList();
public class ViewModelStudent3: Student { public string SchoolName { get; set; } }
生成的Sql以下
SELECT sc.[Name] AS [SchoolName],--這一列神奇的自動出現了 sc.[Id] AS [scId], st.[ID] AS [Id], st.[SchoolId] AS [SchoolId], st.[Name] AS [Name], st.[CreateTime] AS [CreateTime] FROM [STudent] st ,[School] sc WHERE ( [st].[SchoolId] = [sc].[Id])
多表分頁查詢
var list3 = Db.Queryable<Student, School>((st, sc) => new object[] { JoinType.Left,st.SchoolId==sc.Id }).Select<ViewModel>() .ToPageList(pageIndex,pageSize)
子查詢
var getAll = Db.Queryable<Student, School>((st, sc) => new object[] { JoinType.Left,st.Id==sc.Id}) .Where(st => st.Id == SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Select(s => s.Id)) .ToList(); //生成的MYSQL語句,若是是SqlServer就是TOP 1 SELECT `st`.`ID`,`st`.`SchoolId`,`st`.`Name`,`st`.`CreateTime` FROM `STudent` st Left JOIN `School` sc ON ( `st`.`ID` = `sc`.`Id` ) WHERE ( `st`.`ID` =(SELECT `Id` FROM `School` WHERE ( `Id` = `st`.`ID` ) limit 0,1))
一對一的查詢
var getAll = Db.Queryable<Student, School>((st, sc) => new object[] { JoinType.Left,st.Id==sc.Id}) .Select(st => new{ name = st.Name, id = SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Select(s => s.Id) }).ToList();
本文只講重點,更多多表查詢請看 API
http://www.codeisbug.com/Doc/8/1124
若是說 .Select() 也能夠實現一對一的查詢或者一些SQL函數可是畢竟是用來生成SQL的因此有不少侷限性,Mapper是在查詢出結果後進行處理因此任何C#方法都支持
也更強大
var s12 = db.Queryable<Student, School>((st, sc) => st.SchoolId == sc.Id).Select<ViewModelStudent3>() .Mapper(it => { it.Name = Md5(it.Name); //有多少列要處理寫多少列,能用Mapper的就少用Select兼容性更好些 }).ToList();
咱們也能夠用Mapper來實現一對多,彌補.Select()不足
var s12 = db.Queryable<Student, School>((st, sc) => st.SchoolId == sc.Id).Select<ViewModelStudent3>() .Mapper((it, cache) => { var allSchools = cache.GetListByPrimaryKeys<School>(vmodel => vmodel.SchoolId); //in(ViewModelStudent3[0].SchoolId , ViewModelStudent3[1].SchoolId...) /*one to many*/ it.Schools = allSchools.Where(i => i.Id == it.SchoolId).ToList(); /*C# syntax conversion*/ it.Name = it.Name == null ? "null" : it.Name; }).ToList();
一對多查詢的性能能夠秒殺其它ORM ,由於生成的SQL只有2條,而且這2條不會多查詢一條沒用的記錄,有幸趣的能夠研究一下,其它的都內存處理
Union all查詢將結果集合並
var getUnionAllList2 = db.UnionAll(db.Queryable<Student>(), db.Queryable<Student>()).ToList();//union all
兩個Queryable聯表查詢(有人說我只支持12表JOIN,那這樣就能夠支持24張表了)
var q1 = db.Queryable<Student, School>((st,sc)=>new object[] { JoinType.Left,st.SchoolId==sc.Id }).Select((st, sc) => new ViewModelStudent4() { Id=st.Id, Name=st.Name,SchoolName=sc.Name }); var q2 = db.Queryable<School>(); var innerJoinList = db.Queryable(q1, q2, (j1, j2) => j1.Id == j2.Id).Select((j1, j2) => j1).ToList();//inner join var leftJoinList = db.Queryable(q1, q2,JoinType.Left, (j1, j2) => j1.Id == j2.Id).Select((j1, j2) => j1).ToList();/
二級緩存功能是對查詢出來的數據進行緩存,在緩存不失效的狀況下,下次一樣的查詢操做都會從緩存內讀取
var list=db.Queryable<Student, School>((s1, s2) => s1.Id == s2.Id).Select(s1 => s1).WithCache().ToList();//能夠設置過時時間WithCache(60)
咱們須要刪除緩存也至關方便,只須要在對該表操做的時候加 RemoveDataCache 就能把查詢中引用該表的緩存所有清除
db.Deleteable<Student>().Where(it => it.Id == 1).RemoveDataCache().ExecuteCommand();
//Updateable和Insertable同樣用法
SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, MoreSettings =new ConnMoreSettings(){ IsAutoRemoveDataCache=true }
咱們須要建立一個MyCache類,你能夠用我寫好的也能夠用你自已寫的實現緩存
ICacheService myCache = new RedisCache("10.1.249.196");//ICacheService SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true, ConfigureExternalServices = new ConfigureExternalServices() { DataInfoCacheService = new RedisCache() //RedisCache是繼承ICacheService自已實現的一個類 } });
我寫好的Cache類能夠做爲參考
Redis:
https://github.com/sunkaixuan/SqlSugar/blob/dev/Src/Asp.Net/SqlSugar.Extensions.DataCache/RedisCache.cs
.Net自帶Cache:
https://github.com/sunkaixuan/SqlSugar/blob/dev/Src/Asp.Net/SqlSugar.Extensions.DataCache/HttpRuntimeCache.cs
永久開源,源碼下:
https://github.com/sunkaixuan/SqlSugar
SqlSugar一直在默默進步,獲得了一些大型企業的承認,但這只是開始,但願你喜歡。
上一篇