楊中科老師視訊
.NET 5教程,.Net Core 2021視訊教程,楊中科主講_哔哩哔哩_bilibili
一、EF Core一對多關系配置
1、所謂“關系資料庫”
2、複習,資料庫表之間的關系,“一對一” “一對多” “多對多”
多對多表關系通過第三方關系表,保持對應關系
3、三部曲:實體類中關系屬性;Fluent API關系配置;使用關系操作
一對多,實體類
Article public List<Comment> comments {get;set;} = new List<Comment>();
List推薦預設給空集合
Comment public Article Article{get;set;}
套路:HasXXX(...).WithXXX(...) 有XXX,反之帶有XXX
一對多:HasOne(...).WithMany(...)
一對一:HasOne(...).WithOne(...)
多對多:HasMany(...).WithMany(...)
示範:建配置關系,插入資料
EF Core會“順竿爬”,簡化代碼
二、
示範查詢關聯資料,把Article以及所有Comment查詢出來
Article a=ctx.Article.Include(a=>a.Commentts).Single(a=>a.id==2);
Include:同時查詢關聯的對象
EF Core中目前沒有一種方式讓生成的sql采用那種join;
三、額外的外鍵字段,需求:隻想獲得ArticleId和Comment,不要Article其他字段
SQL優化,盡量不要select * 原則,采用Linq select 匿名類
在查詢時,使用select可以省略寫Include,但是SQL還是會join
步驟:
1、在實體類中顯式聲明一個外鍵屬性
2、在關系配置中通過 HasForeignKey(c=>c.ArticleId) 指定這個屬性為外鍵
3、除非必要,否則不用聲明外鍵列,因為會引入重複
EF Core:大部分查詢比絕大部分程式員寫出來的SQL性能都要高,有少部分SQL語句性能可能不盡如人意,但是也影響不大,特殊的一些SQL語句可能影響性能瓶頸,咱們再需要特殊優化
四、EF Core 單向導航屬性
導航屬性:在自己類中可以通路其他類的屬性,例如:Comments
雙向導航屬性的問題,基礎表被多個其他表引用時麻煩
單向導航對應結構
HasOne<User>(u=>u.Requester).WithMany() WithMany不設定參數
選擇
對于主從結構的“一對多”表關系,一般是聲明雙向導航屬性,而對于其他的“一對多”表關系,如果表屬于被很多表引用的基礎表,則用單向導航屬性,否則可以自由決定是否是雙向導航屬性;
五、關系配置在任何一方都可以 推薦配置在多的那一端
正反都一樣 一對多,多對一
示範配置放在另一方配置中
HasOne<Article>(c=>c.Article).WithMany(a=>a.Comments)
同等于 HasMany<Commentt>(a=>a.Comments).WithOne(c=>c.Article)
推薦政策,考慮到有單向導航屬性的可能,我們一般用HasOne().WithMany(),關系配置到多的那一端;
六、自引用的組織結構樹 類似字典表結構,ParentId是本身表的Id
代碼示範, 利用“順竿爬”兩種方式二選一
自己研究下,這個地方優點繞,測試一下代碼,插入資料
遞歸查詢資料
new String('.',3) 指定字元重複若幹次 new String('\t',3) 三個制表符
七、一對一
必須顯式的在其中一個實體類中聲明一個外鍵屬性(在一對多中必要時才聲明外鍵屬性,一般不聲明)
bulider.HasOne<Delivery>(o=>o.Delivery).WithOne(d=>d.order)
.HasForeignKey<Delivery>(d=>d.orderId);
外鍵屬性在Deliver類中,配置外鍵在OrderConfig類中,是否可以調換位置呢??可以,配置在哪邊都行
可以不用“順竿爬”都存起來,靠譜;
八、多對多 EF Core5.0開始,才正式支援多對多
資料庫中需要中間表
builder.HasMany<Teacher>(s=>s.Teachers).WithMany(t=>t.Students)
.UsingEntity(j=>j.ToTable("T_Students_Teachers"));
UsingEntity 設定中間表表名
代碼示範,總結
九、基于關系的複雜查詢,性能調優
eg:查找評論中含有“微軟”兩個子的所有文字(文字和評論是雙向導航屬性)
1、var items = ctx.Articles.Where(a=>a.Comments.Any(c=>c.Message.Contains("微軟")));
2、var items = ctx.Comments.where(c=>c.Message.Contains("微軟")).Select(c=>c.TheArticle).Distinct(); Distinct 去重
兩種實作方式生成的sql不一樣,可以對比調優