FreeSql 支持導航屬性延時加載,即當咱們須要用到的時候才進行加載(讀取),支持1對一、多對一、1對多、多對多關係的導航屬性。html
當咱們但願瀏覽某條訂單信息的時候,才顯示其對應的訂單詳細記錄時,咱們但願使用延遲加載來實現,這樣不只加快的了 讀取的效率,同時也避免加載不須要的數據。延遲加載一般用於foreach循環讀取數據時。sql
那麼咱們在定義Model的時候,須要在屬性前面添加virtual關鍵字。以下數據庫
public class Order { [Column(IsPrimary = true)] public int OrderID { get; set; } public string OrderTitle { get; set; } public string CustomerName { get; set; } public DateTime TransactionDate { get; set; } public virtual List<OrderDetail> OrderDetails { get; set; } } public class OrderDetail { [Column(IsPrimary = true)] public int DetailId { get; set; } public int OrderId { get; set; } public virtual Order Order { get; set; } }
延時加載功能默認被關閉的,使用此功能請時,請在申明處開啓;性能
延時加載功能,依賴 FreeSql.Extensions.LazyLoading 包,請前往 nuget 下載;ui
IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") .UseLazyLoading(true) //開啓延時加載功能 .UseMonitorCommand( cmd => Console.WriteLine(cmd.CommandText)) //監聽SQL命令對象,在執行前 .Build(); var order = fsql.Select<Order>().Where(a => a.OrderID == 1).ToOne(); //查詢訂單表 var orderDetail1 = order.OrderDetails; //第一次訪問,查詢數據庫 var orderDetail2 = order.OrderDetails; //第二次訪問,不查 var order1 = orderDetail1.FirstOrDefault(); //訪問導航屬性,此時不查數據庫,由於 OrderDetails 查詢出來的時候已填充了該屬性
控制檯輸出內容:code
SELECT a.`OrderID`, a.`OrderTitle`, a.`CustomerName`, a.`TransactionDate` FROM `Order` a WHERE (a.`OrderID` = 1) limit 0,1 SELECT a.`DetailId`, a.`OrderId` FROM `OrderDetail` a WHERE (a.`OrderId` = 1)
FreeSql延時加載支持1對一、多對一、1對多、多對多關係的導航屬性,前三者大小同異,如下咱們單獨介紹多對多關係。htm
public partial class Song { [Column(IsIdentity = true)] public int Id { get; set; } public DateTime? Create_time { get; set; } public bool? Is_deleted { get; set; } public string Title { get; set; } public string Url { get; set; } public virtual ICollection<Tag> Tags { get; set; } } public partial 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; } } public partial class Tag { [Column(IsIdentity = true)] public int Id { get; set; } public int? Parent_id { get; set; } public virtual Tag Parent { get; set; } public decimal? Ddd { get; set; } public string Name { get; set; } public virtual ICollection<Song> Songs { get; set; } }
如上有三個表,音樂、標籤,以及他們的關係表。對象
var songs = fsql.Select<Song>().Limit(10).ToList(); //取10條音樂 var songs1 = songs.First().Tags; //第一次訪問,查詢數據庫 var songs2 = Songs.First().Tags; //第二次訪問,不查
控制檯輸出內容:blog
SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` FROM `Song` a limit 0,10 SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` FROM `Tag` a WHERE (exists(SELECT 1 FROM `Song_tag` b WHERE (b.`Song_id` = 2 AND b.`Tag_id` = a.`Id`) limit 0,1))
優勢:只在須要的時候加載數據,不須要預先計劃,避免了各類複雜的外鏈接、索引、視圖操做帶來的低效率問題。索引
缺陷:屢次與DB交互,性能下降。
若是要在循環中使用數據,請使用貪婪加載,不然使用懶加載。
(二十五)延時加載