上海網(wǎng)站制作上海網(wǎng)站制作重慶森林壁紙
????.NET開源 ORM 框架 SqlSugar 系列
- 【開篇】.NET開源 ORM 框架 SqlSugar 系列
- 【入門必看】.NET開源 ORM 框架 SqlSugar 系列
- 【實(shí)體配置】.NET開源 ORM 框架 SqlSugar 系列
- 【Db First】.NET開源 ORM 框架 SqlSugar 系列
- 【Code First】.NET開源 ORM 框架 SqlSugar 系列
- 【數(shù)據(jù)事務(wù)】.NET開源 ORM 框架 SqlSugar 系列
- 【連接池】.NET開源 ORM 框架 SqlSugar 系列
- 【查詢目錄】.NET開源 ORM 框架 SqlSugar 系列
- 【查詢基礎(chǔ)】.NET開源 ORM 框架 SqlSugar 系列
- 【排序用法】.NET開源 ORM 框架 SqlSugar 系列
- 【分組去重】.NET開源 ORM 框架 SqlSugar 系列
- 【聯(lián)表查詢】.NET開源 ORM 框架 SqlSugar 系列
- 【導(dǎo)航查詢】.NET開源 ORM 框架 SqlSugar 系列
- 【子查詢】.NET開源 ORM 框架 SqlSugar 系列
- 【嵌套查詢】.NET開源 ORM 框架 SqlSugar 系列
💦萬(wàn)丈高樓平地起,做開發(fā)想要技術(shù)精進(jìn),必須要有扎實(shí)的基礎(chǔ)功底?;A(chǔ)SQL查詢語(yǔ)法一定要牢記于心,才能應(yīng)對(duì)后面更為復(fù)雜的形勢(shì)。
💥SqlSugar 在子查詢上支持是非常強(qiáng)大,比如 子查詢進(jìn)行聯(lián)表、IN、NOT IN 和 SELECT 一列等 。
1、基礎(chǔ)教程?🎀
?1.1 API目錄
/***只查一列***/
//First: select top 1 id
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Select(s => s.Id)
//max例1:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Max(s => s.Id)
//max例2:
SqlFunc.Subqueryable<School>()..Where(s=>s.Id==st.Id).Select(s=>SqlFunc.AggregateMax(s.Id))
//min:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Min(s => s.Id)
//avg:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Avg(s => s.Id)
//count:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Count()
//sum:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Sum(s => s.num)
//去重后匯總數(shù)量
SqlFunc.Subqueryable<School>().Where(s => z.Id == st.Id).Select(s=>SqlFunc.AggregateDistinctCount(s.Name))
//逗號(hào)分割列
SqlFunc.Subqueryable<Order>().Where(z=>z.Id==it.Id).SelectStringJoin(z => z.Name, ",")
//完整用例:看標(biāo)題8/***返回List或者實(shí)體***/
新功能:5.1.3.36
//SqlFunc.Subqueryable<Custom>().Where(c => c.Id == it.CustomId).ToList()
//SqlFunc.Subqueryable<Custom>().Where(c => c.Id == it.CustomId).ToList(it=>new Class(){ Name=it.Name})
//更多看標(biāo)題4/***返回單個(gè)實(shí)體***/
//SqlFunc.Subqueryable<Custom>().Where(c => c.Id == it.CustomId).First()
//更多看標(biāo)題9/***IN、Not in、Exists、Not Exists***/
//看標(biāo)題2
1.2 where 中使用
var getAll = db.Queryable<Student, School>((st, sc) => new JoinQueryInfos(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語(yǔ)句,如果是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))
*/
1.3 在 select 中使用
2、IN和NOT IN的操作?🎀
?2.1 Exists?
?Exists 和 in 區(qū)別在于?Exists 擴(kuò)展性更強(qiáng),支持多個(gè)字段 (簡(jiǎn)單的說(shuō) In 能實(shí)現(xiàn)的 Exists 都能實(shí)現(xiàn))
//等同于IN
var getAll7 = db.Queryable<Student>()
.Where(it => SqlFunc.Subqueryable<School>().Where(s =>s.Id==it.Id).Any()).ToList();/*生成的SQL(等于同于it.id in(select id from school)只是寫法不一樣
SELECT `ID`,`SchoolId`,`Name`,`CreateTime` FROM `STudent` it
WHERE (EXISTS ( SELECT * FROM `School` WHERE ( `Id` = `it`.`ID` ) ))
*///等同于NOT IN
var getAll8 = db.Queryable<Student>().Where(it =>
SqlFunc.Subqueryable<School>().Where(s => s.Id == it.Id).NotAny()).ToList();/*生成的SQL
SELECT `ID`,`SchoolId`,`Name`,`CreateTime` FROM `STudent` it
WHERE (NOT EXISTS ( SELECT * FROM `School` WHERE ( `Id` = `it`.`ID` ) ))
*///搜索關(guān)鍵詞:exits
2.2 In 和 Not In (5.0.7.5)??
在有 GroupBy 的情況下==自動(dòng)轉(zhuǎn)成? in?
db.Queryable<Order>()
.Where(it=>it.Id==SqlFunc.Subqueryable<Custom>().GroupBy(z=>z.OrderId).Select(z=>z.OrderId)).ToList()//Sql
//SELECT [Id],[Name] FROM [Order]
// WHERE [Id] in ((SELECT [OrderId] FROM [Custom] GROUP BY [OrderId]))
2.3 分頁(yè)In
db.Queryable<Order>().In(it=>it.Id,db.Queryable<Order>().Skip(1).Take(100).Select(it=>it.Id)).ToList();
3、子查詢中使用Sql?🎀
最新版本才支持
string sql=" (select top 1 id from [Order] ) ";var list = db.Queryable<Order>().Select(it => new{name=it.Name,customName= SqlFunc.MappingColumn<string>(sql)//老版本MappingColumn(default(string),sql) }).ToList();//如果存在SQL拼接將SQL提取到外面在傳進(jìn)來(lái),有些VS拼接會(huì)有問(wèn)題
Sql代碼如下:
SELECT [Name] AS [name] , (select top 1 id from [Order] ) AS [customName] FROM [Order]
4、ToList()集合對(duì)象?🎀
方式1:簡(jiǎn)單方式(5.1.3.38)
直接在 Select 中進(jìn)行?ToList? ,
性能:? ?大于循環(huán)數(shù)倍? ,大部分情況性能小于ThenMapper方式和導(dǎo)航 ,寫法簡(jiǎn)單性能也說(shuō)的過(guò)去
//請(qǐng)升級(jí)到 5.1.3.36+ db.Queryable<Order>().Select(it => new{CustomId = it.CustomId,OrderId = it.Id,OrderName = it.Name,CustomList = SqlFunc.Subqueryable<Custom>().Where(c => c.Id == it.CustomId).ToList()}).ToList();//也可以DTOSqlFunc.Subqueryable<Custom>().Where(c=> c.Id == it.CustomId).ToList(c=> new Class(){ Name=c.Name}) //轉(zhuǎn)成DTO//注意:where ToList里面 c 的別名要一致//只查L(zhǎng)ist<string>這種集合
SqlFunc.Subqueryable<Custom>().Where(c => c.Id == it.CustomId).ToList(c=>c.Name)//最新版本//自動(dòng)DTO 5.1.4.70
SqlFunc.Subqueryable<Custom>().Where(c => c.Id == it.CustomId).ToList<DTO>()
SqlFunc.Subqueryable<Custom>().Where(c => c.Id == it.CustomId).ToList(it=>new DTO(){},true);//和Queryable類似
方式2:性能、功能、跨庫(kù)
該功能在同類框架中性能比較好不會(huì)生成垃圾SQL ,?在現(xiàn)有結(jié)果進(jìn)行一對(duì)多操作
var treeRoot=db.Queryable<Tree>().ToList();//可以聯(lián)表查詢,只要返回List中有關(guān)聯(lián)字段就可以//填充子對(duì)象
//原理: 數(shù)據(jù)庫(kù)一次讀取 In (list[0].id,list[1].id,list[2].id...) 內(nèi)存分配到對(duì)應(yīng)Child
//所以無(wú)論集合多少條記錄 ThenMapper 只會(huì)操作一次庫(kù)
db.ThenMapper(treeRoot, item =>{ //用例1:簡(jiǎn)單填充 //參數(shù)解釋:子表的ParentId和主表的Id 進(jìn)行關(guān)聯(lián)查詢(有Select寫到SetContext前面)//可以額外加Where寫SetContext前面,但是不能帶有item對(duì)象,item要寫SetContext里面item.Child = db.Queryable<Tree>().SetContext(x => x.ParentId, () => item.Id, item).ToList();//用例2:可以多屬性//item.Child=xxxx//item.Parent=xxxx//用例3:類型轉(zhuǎn)換類轉(zhuǎn)成DTO (注意:Select中的關(guān)聯(lián)字段要賦值)//item.Child = db.Queryable<Tree>()// .Select(it=>new ViewTree(){ParentId=x.ParentId,Id=i.Id,Name=it.Name }) // .SetContext(x => x.ParentId, () => item.Id, item).ToList();//用例4:聯(lián)表填充//item.Child=db.Queryable<Tree>()//.LeftJoin<Tree>((i,y)=>i.ParentId==y.Id)//.Select((i,y)=>new viewmodel(){ Parentid=i.Parentid..........})//.SetContext(x => x.ParentId, () => item.Id, item).ToList();});//異步
var treeRoot=await db.Queryable<Tree>().ToListAsync();
await db.ThenMapperAsync(treeRoot, async item =>
{ //給集合賦值 參數(shù)解釋 子表的ParentId和主表的Id 進(jìn)行關(guān)聯(lián)查詢item.Child =await db.Queryable<Tree>().SetContextAsync(x=>x.ParentId,()=>item.Id, item);
});//無(wú)限層級(jí)
var treeRoot=db.Queryable<Tree>().Where(it => it.Id == 1).ToList();
//第一層
db.ThenMapper(treeRoot, item =>
{item.Child = db.Queryable<Tree>().SetContext(x => x.ParentId, () => item.Id, item).ToList();
});
//第二層
db.ThenMapper(treeRoot.SelectMany(it=>it.Child), it =>
{it.Child = db.Queryable<Tree>().SetContext(x => x.ParentId, () => it.Id, it).ToList();
});//跨庫(kù)
var mydb=db.GetConnection(1);
mydb.ThenMapper(root,item=>{...});
方式3:導(dǎo)航方式
這種已經(jīng)不屬于子查詢了,屬于另一個(gè)查詢體系。
5、子查詢?cè)贘oin?🎀
5.0.5.4+
var list = db.Queryable<Order>().Where(it =>SqlFunc.Subqueryable<A>() .LeftJoin<B>((i,y)=>i.ItemId==y.ItemId).InnerJoin<C>((i,y,z) => i.ItemId == z.ItemId).Where((i,y,z)=>i.ItemId==it.Aid).Any()).ToList();
//新版本支持了Subquery.join使用 Where<T1,T2>((x,y)=> x.id==y.id)
6、子查詢使用別名?🎀
如果點(diǎn)不出 AS 請(qǐng)升級(jí)
SqlFunc.Subqueryable<A>().AS("A01") //這樣查詢的就是 A01表
7、字符串拼接
5.1.1-preview14 逗號(hào)拼接
//sqlerver : FOR XML PATH//mysql sqlite : group_concat//oracle : listagg//pgsql :string_aggvar list= db.Queryable<Order>().Select(it => new{ //names="名字1,名字2,名字3"names=SqlFunc.Subqueryable<custom>().Where(z=>z.oid==it.id).SelectStringJoin(z => z.Name, ",")}).ToList();//多字段 不能有null相加 , 字段有null需要加上 z.Name??""
.SelectStringJoin(z => SqlFunc.MergeString(z.Name,"-",z.Id.ToString()), ",")//去重復(fù)
.SelectStringJoin(it=>SqlFunc.MappingColumn<string>($"distinct {it.UserId}"),".")
8、只查一列 (top 1)
//First:select top 1 id
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Select(s => s.Id)
//max例1:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Max(s => s.Id)
//max例2:
SqlFunc.Subqueryable<School>().Where(s=>s.Id==st.Id).Select(s=>SqlFunc.AggregateMax(s.Id))
//min:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Min(s => s.Id)
//avg:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Avg(s => s.Id)
//count:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Count()
//sum:
SqlFunc.Subqueryable<School>().Where(s => s.Id == st.Id).Sum(s => s.num)
//去重后匯總數(shù)量
SqlFunc.Subqueryable<School>().Where(s => z.Id == st.Id).Select(s=>SqlFunc.AggregateDistinctCount(s.Name))
//逗號(hào)分割列
SqlFunc.Subqueryable<Order>().Where(z=>z.Id==it.Id).SelectStringJoin(z => z.Name, ",")//用例
Select(it=>new{ id=it.id,schoolname=SqlFunc.Subqueryable<School>().Where(s=>s.Id==it.ShoolId).Select(s=>s.Name) //對(duì)應(yīng)的Sql: //schoolname=(SELECT `Name` FROM `School` `s` WHERE (`s`.`Id`=`it`.`ShoolId`)limit 0,1)})//如果要查整個(gè)對(duì)象:看標(biāo)題9
9、子查詢 First()整個(gè)對(duì)象
//需要升級(jí)5.1.4.59
var list= db.Queryable<Order>().Select(it => new{CustomId = it.CustomId,OrderId = it.Id,OrderName = it.Name,CustomList = SqlFunc.Subqueryable<Custom>().Where(c => c.Id == it.CustomId).First()}).ToList();
//可以轉(zhuǎn)DTO
SqlFunc.Subqueryable<Custom>().Where(c => c.Id == it.CustomId).First(c=>new xxx(){ yy=c.id })//如果只查一個(gè)字段:標(biāo)題8
????.NET開源 ORM 框架 SqlSugar 系列
- 【開篇】.NET開源 ORM 框架 SqlSugar 系列
- 【入門必看】.NET開源 ORM 框架 SqlSugar 系列
- 【實(shí)體配置】.NET開源 ORM 框架 SqlSugar 系列
- 【Db First】.NET開源 ORM 框架 SqlSugar 系列
- 【Code First】.NET開源 ORM 框架 SqlSugar 系列
- 【數(shù)據(jù)事務(wù)】.NET開源 ORM 框架 SqlSugar 系列
- 【連接池】.NET開源 ORM 框架 SqlSugar 系列
- 【查詢目錄】.NET開源 ORM 框架 SqlSugar 系列
- 【查詢基礎(chǔ)】.NET開源 ORM 框架 SqlSugar 系列
- 【排序用法】.NET開源 ORM 框架 SqlSugar 系列
- 【分組去重】.NET開源 ORM 框架 SqlSugar 系列
- 【聯(lián)表查詢】.NET開源 ORM 框架 SqlSugar 系列
- 【導(dǎo)航查詢】.NET開源 ORM 框架 SqlSugar 系列
- 【子查詢】.NET開源 ORM 框架 SqlSugar 系列
- 【嵌套查詢】.NET開源 ORM 框架 SqlSugar 系列