首页 > 代码库 > Linq的延迟加载问题
Linq的延迟加载问题
什么是延迟加载:所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。可以简单理解为,只有在使用的时候,才会发出sql语句进行查询,数据是分N次读取。
什么是立即加载:所谓立即加载既是所有的相关数据一次被读取出来,而不是分N次。
相信上面的概念大家都知道,接下来举个例子说明一下:
ClassInfo表:
StuInfo表:
2个表的关系就不要我多说了
一、接下来看延迟加载代码:
LinqDBDataContext db = new LinqDBDataContext(); db.DeferredLoadingEnabled = true;//true表示延迟加载,默认就是延迟加载,所以本句代码可以省略 string path = Server.MapPath(@"~/Log/log.txt"); StreamWriter sw = File.AppendText(path); db.Log = sw; //创建Linq to sql语句 var list = from s in db.ClassInfo select s; //编辑SQL语句 foreach (var c in list) { string s1 = string.Format("班级ID:{0},班级名称:{1}<br>", c.ClassID, c.ClassName); Response.Write(s1); foreach (var mark in c.StuInfo) { string s2 = string.Format("学号:{0},姓名:{1}<br>", mark.StuNum, mark.StuName); Response.Write(s2); } } db.Log.Flush(); db.Log.Close();
输出的结果是:
班级ID:1,班级名称:T1001
学号:S001,姓名:张小三
学号:S004,姓名:王五
学号:S006,姓名:小明
学号:S007,姓名:郭晓明
学号:S009,姓名:张宝
班级ID:2,班级名称:T1002
学号:S002,姓名:李四
学号:S003,姓名:小丽
学号:S008,姓名:张洁
学号:S011,姓名:王燕
学号:S012,姓名:王胜
班级ID:3,班级名称:T1003
学号:S005,姓名:赵六
学号:S010,姓名:陈明
班级ID:4,班级名称:T1004
学号:S013,姓名:王倩
日志输出的内容如下:
SELECT [t0].[ClassID], [t0].[ClassName]FROM [dbo].[ClassInfo] AS [t0]-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.18058SELECT [t0].[StuNum], [t0].[StuName], [t0].[StuAge], [t0].[StuSex], [t0].[ClassID]FROM [dbo].[StuInfo] AS [t0]WHERE [t0].[ClassID] = @p0-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1]-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.18058SELECT [t0].[StuNum], [t0].[StuName], [t0].[StuAge], [t0].[StuSex], [t0].[ClassID]FROM [dbo].[StuInfo] AS [t0]WHERE [t0].[ClassID] = @p0-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [2]-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.18058SELECT [t0].[StuNum], [t0].[StuName], [t0].[StuAge], [t0].[StuSex], [t0].[ClassID]FROM [dbo].[StuInfo] AS [t0]WHERE [t0].[ClassID] = @p0-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [3]-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.18058SELECT [t0].[StuNum], [t0].[StuName], [t0].[StuAge], [t0].[StuSex], [t0].[ClassID]FROM [dbo].[StuInfo] AS [t0]WHERE [t0].[ClassID] = @p0-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [4]-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.18058
通过日志可以看出来,外层的foreach是遍历ClassInfo,产生了查询ClassInfo的一句日志,里层foreach是遍历每个ClassInfo里面的StuInfo,由于有4个班,要查询4个ClassInfo里面的StuInfo,所以会产生4句日志。这种情况就是真正需要数据时,才进行查询。
二、接下来看立即加载的代码:
LinqDBDataContext db = new LinqDBDataContext(); db.DeferredLoadingEnabled = false;//false表示立即加载 string path = Server.MapPath(@"~/Log/log.txt"); StreamWriter sw = File.AppendText(path); db.Log = sw; //立即加载模式(下面3句代码一定要加,否则学生信息查不到数据) DataLoadOptions dl = new DataLoadOptions(); dl.LoadWith<ClassInfo>(s => s.StuInfo); db.LoadOptions = dl; //创建Linq to sql语句 var list = from s in db.ClassInfo select s; //编辑SQL语句 foreach (var c in list) { string s1 = string.Format("班级ID:{0},班级名称:{1}<br>", c.ClassID, c.ClassName); Response.Write(s1); foreach (var mark in c.StuInfo) { string s2 = string.Format("学号:{0},姓名:{1}<br>", mark.StuNum, mark.StuName); Response.Write(s2); } } db.Log.Flush(); db.Log.Close();
输出来的结果和上面的一样,但是我们看看日志信息:
SELECT [t0].[ClassID], [t0].[ClassName], [t1].[StuNum], [t1].[StuName], [t1].[StuAge], [t1].[StuSex], [t1].[ClassID] AS [ClassID2], ( SELECT COUNT(*) FROM [dbo].[StuInfo] AS [t2] WHERE [t2].[ClassID] = [t0].[ClassID] ) AS [value]FROM [dbo].[ClassInfo] AS [t0]LEFT OUTER JOIN [dbo].[StuInfo] AS [t1] ON [t1].[ClassID] = [t0].[ClassID]ORDER BY [t0].[ClassID], [t1].[StuNum]-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.18058
很明显立即加载,是一次性进行查询读取出来的。
Linq的延迟加载问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。