貪婪加載顧名思議就是把全部要加載的東西一次性讀取。html
本節內容爲了配合【延時加載】而誕生,貪婪加載和他本該在一塊兒介紹,開發項目的過程當中應該左右開弓,才能寫出高質量的程序。sql
Select<Tag>().Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); Select<Tag>().Limit(10).ToList(a => new TestDto()); Select<Tag>().Limit(10).ToList(a => new TestDto { }); Select<Tag>().Limit(10).ToList(a => new TestDto() { }); Select<Tag>().Limit(10).ToList<TestDto>();
這種映射支持單表/多表。性能
查找規則,查找屬性名,會循環內部對象 _tables(join 查詢後會增加),以 主表優先查,直到查到相同的字段。code
如:sqlite
A, B, C 都有 id,Dto { id, a1, a2, b1, b2 },A.id 被映射。也能夠指定 id = C.id 映射。htm
友情提醒:在 dto 能夠直接映射一個導航屬性對象
ManyToOne/OneToOne 導航屬性經過 ToList() 加載,這個方法有一個參數:includeNestedMembers。blog
參數說明:事務
false: 返回 2級 Join 的數據;內存
true: 返回全部層級深度 Join 的導航數據;
若是查詢中已經使用了 a.Parent.Parent 相似表達式,則能夠無需 LeftJoin 等操做。
如:
Select<Tag>().Where(a => a.Parent.Name == "1").ToList(); //這樣寫,不須要再標記 Join,解析表達式時自動處理成 LeftJoin
若是導航屬性沒有使用,又想加載,可以使用 Include 方法。
Select<Tag>().Include(a => a.Parent).ToList();
IncludeMany 貪婪加載集合的導航屬性,實際上是分兩次查詢,在 ToList 後進行了數據重裝。
Select<Tag>().IncludeMany(a => a.Songs).ToList(); //這是 ManyToMany 關係的貪婪加載
OneToMany 的使用方法相同
IncludeMany 有第二個參數,能夠進行二次查詢前的修飾工做。
Select<Tag>().IncludeMany(a => a.Songs, then => then.Where(song => song.User == "admin")).ToList();
而後,其實在 then 那裏,還能夠繼續進行向下 Include/IncludeMany。只要你喜歡,向下 100 層都沒問題。
變異的 IncludeMany,即便選擇的不是導航屬性,也能夠貪婪加載。
Select<Tag>().IncludeMany(a => a.TestManys.Where(b => b.TagId == a.Id));
支持聯合鍵關係指定
好比 EFCore include 吧,如何只查詢每項子集合的前幾條數據,它只能夠加載全部致使IO性能低下(若是某些子集合,有100條,200條),FreeSql 能夠解決這個問題。
Select<Tag>().IncludeMany(a => a.TestManys.Take(10));
前面介紹 ISelect 中進行貪婪加載集合屬性數據,主數據與子數據查詢必須在一個代碼邏輯內完成。
當主數據已存在內存中,子數據怎麼加載?因此咱們增長了 List<T> 擴展方法,示例以下:
new List<Song>(new[] { song1, song2, song3 }).IncludeMany(g.sqlite, a => a.Tags);
這是一個擴展方法(IncludeMany),方法名與 ISelect.IncludeMany 同名,參數基本一致(除了須要額外傳遞 IFreeSql 對象參數),功能也一致(包括前面提到的變異)。
(二十六)貪婪加載 Include、IncludeMany、Dto、ToList