FreeSql 在通過6個月的開發和朋友們的工做實踐,不斷的改進創新,目前擁有1500個左右單元測試方法,且每一個方法內又覆蓋不一樣的測試面。git
今天介紹 FreeSql 各類貪婪加載的姿式,做下總結。本節內容對應的還有【延時加載】,貪婪加載和他本該在一塊兒介紹,開發項目的過程當中應該左右開弓,才能寫出高質量的程序。有關延時加載,往後有空再單獨編寫。github
FreeSql是一個功能強大的NETStandard庫,用於對象關係映射程序(O/RM),便於開發人員可以使用 .NETStandard 對象來處理數據庫,沒必要常常編寫大部分數據訪問代碼。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 查詢後會增加),以 主表優先查,直到查到相同的字段。數組
如:異步
A, B, C 都有 id,Dto { id, a1, a2, b1, b2 },A.id 被映射。也能夠指定 id = C.id 映射。函數
還能夠在 dto 能夠直接映射一個導航屬性。性能
對頭,經過映射某對象,也能夠實現貪婪加載,這個功能是在數據庫查詢前映射的,而不是查回全部數據再重組。單元測試
ManyToOne/OneToOne 導航屬性經過 ToList() 加載,這個方法有一個參數:includeNestedMembers。測試
參數說明:
false: 返回 2級 Join 的數據;
true: 返回全部層級深度 Join 的導航數據;
若是查詢中已經使用了 a.Parent.Parent 相似表達式,則能夠無需 LeftJoin 等操做。
如:
class Tag { [Column(IsIdentity = true)] public int Id { get; set; } public string Name { get; set; } public int? Parent_id { get; set; } public virtual Tag Parent { get; set; } } Select<Tag>().Where(a => a.Parent.Name == "1").ToList(); //這樣寫,不須要再標記 Join,解析表達式時自動處理成 LeftJoin
若是導航屬性沒有使用,又想加載,可以使用 Include 方法。(很差理解可跳過,也許只能在使用中體會)
Select<Tag>().Include(a => a.Parent).ToList();
IncludeMany 貪婪加載集合的導航屬性,實際上是分兩次查詢,在 ToList 後進行了數據重裝。
class Song { [Column(IsIdentity = true)] public int Id { get; set; } public string Title { get; set; } public virtual ICollection<Tag> Tags { get; set; } } class Song_tag { public int Song_id { get; set; } public virtual Song Song { get; set; } public int Tag_id { get; set; } public virtual Tag Tag { get; set; } } Select<Tag>().IncludeMany(a => a.Songs).ToList(); //這是 ManyToMany 關係的貪婪加載
IncludeMany 有第二個參數,能夠進行第二次查詢前的修飾工做。
Select<Tag>().IncludeMany(a => a.Songs, then => then.Where(song => song.User == "admin")).ToList();
而後,其實在 then 那裏,還能夠繼續進行向下 Include/IncludeMany。只要你喜歡,向下 100 層都沒問題。
大致與 ManyToMany 用法相同,只是它沒有經過中間表查詢數據。
變異的 IncludeMany,即便選擇的不是導航屬性,也能夠貪婪加載。適合一些些老項目,導航屬性配置不規則的,也能夠一對多貪婪加載。
爲了方便理解,我建立了下面兩個類,他們沒有配置導航關係。你可能會問爲啥不配置?我這樣是爲了直觀理解、這樣是爲了直觀理解、這樣是爲了直觀理解!!
class Order { public Guid id { get; set; } public string xxx { get; set; } public List<OrderDetail> Details { get; set; } } class OrderDetail{ public Guid id { get; set; } public string detailTestField { get; set; } public Guid OrderId { get; set; } } Select<Order>().IncludeMany(a => a.Details.Where(b => b.OrderId == a.Id)).ToList();
OK,這樣查詢 order 時,會把 details 也查詢回來。
咱們有考慮在 then 那裏實現 limit(5) 功能,場景是隻查詢每一個子記錄的前5條回來(待實現)。
開源地址:https://github.com/2881099/FreeSql
感謝一直支持的朋友們!