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交互,性能下降。
若是要在循环中使用数据,请使用贪婪加载,不然使用懒加载。
(二十五)延时加载