Linq 查询延迟加载整理笔记
- 观察下面的代码,以及监控sql脚本执行情况
代码片段如下:
打开sql监控操作
下一步:
下一步
请看代码片段:
using (DataModelContainer dbContext = new DataModelContainer())
{
var data = from u in dbContext.Hep_User
select u;
//关键点:查看代码运行到此处的时候,sql脚本监控执行情况。
foreach (var user in data)
{
Console.WriteLine("姓名:"+user.UserName+" "+"账号:"+user.UserAccount);
}
}
下一步
下一步
下一步
再观察下面添加ToList()代码之后的执行现象
注意:ToList()在dbContext.Hep_User.ToList()
using (DataModelContainer dbContext = new DataModelContainer())
{
var data = from u in dbContext.Hep_User.ToList()//注意此处变了,加了一步ToList()操作
select u;
string temp = "--此处代码为了隔离断点,更直观的观察断点还没走到foreach循环时的脚本监控前后情况--";
//关键点:查看代码运行到此处的时候,sql脚本监控执行情况。
foreach (var user in data)
{
Console.WriteLine("姓名:"+user.UserName+" "+"账号:"+user.UserAccount);
}
}
下一步
现象分析总结:
观察两片代码执行的现象,我们能够发现Linq从数据库表中提取数据时的两种方式:
(1)第一种:ToList()直接即时将表中的数据提取到内存当中;
缺点:当表中的数据量很大的时候,非常消耗内存,占用内存资源,拖慢程序的性能。
(2)第二种:没有使用Tolist(),直接用var data(其实就是IQueryable类型)接收,然后foreach遍历data;此时当遍历到data时,直接从数据库中提取想要的数据,而不是把所有的数据放到程序的内存当中根据条件进行筛选。
优点:对程序的内存消耗小,在数据库中就对数据进行了过滤和提取。
(3)其实就是:Linq查询在【数据库中】和【程序内存中】的两种过滤方式;其本质区别需要探索研究IQueryable 和List< T >两种接收Linq查询结果的类型(IQueryable < T >),涉及到逆变和协变,请看下一篇章的逆变与协变的个人理解笔记