LINQ to SQL系列三 使用DeferredLoadingEnabled,DataLoadOption指定加载选项
2010-05-17 09:02
387 查看
本文中举例用到的数据模型如下:
Student和Class之间是多对一关系,Student和Course之间是多对多关系。
DataContext的DeferredLoadingEnabled属性指定是否需要延时加载,其默认值为true。以Student为例,其延时加载的对象是指Class和对应的Course。设定延时加载为true时,当访问到Student实例的Class属性或者StudentCourse属性时会自动加载Class表和StudentCourse表中的数据,如下示例代码:
用到了两个sql语句,在我们访问到Student的Class属性时,DataContext自动去加载了Class的数据。
在有些时候可以将DeferredLoadingEnabled属性设置为false,设置为false时再直接访问Student的Class属性时将抛出空引用的异常。
有了延时加载,LoadWith方法是做什么用的呢?
MSDN上对LoadWith的解释是:通过使用 lambda 表达式检索与主目标相关的指定数据。
LoadWith不是DataContext的方法,而是DataLoadOptions的方法,可以给DataContext设定LoadOptions属性来改变DataContext加载数据的方式;换句话说是LoadOptions设定是否在select主表数据时同时用join加载关联表的数据。
假定场景:我希望在select Student表的数据时同时用一个sql将其class的属性select出来,如下代码:
这次执行只用了一个SQL语句,Student表inner join Class表,这就是LoadWith的意义所在。
LoadWith可以用一个sql语句加载相关表的数据,那么AssociateWith 方法又是做什么用的呢?
还是假定一个场景,我们想知道某个班级的信息和这个班级中体重大于30公斤的学生的信息,也就是说在取得关联表数据时附加了条件,请看下面的代码及注释:
可以看到是两个sql语句,第二个sql语句中AssociateWith起了作用,第一个条件是体重大于@p0,第二个条件是classID;可以看到这儿生成的sql语句很不好,ClassID是唯一主键,按理说DataContext已经知道这事儿,但是在生成语句时还是用了嵌套的查询,可以说是LINQ to SQL的一个败笔。
linq to sql相关随笔:
1. 从CUD开始,如何使用LINQ to SQL插入、修改、删除数据
2. 查询 使用LINQ to SQL做简单查询
3. 查询 延迟加载与立即加载,使用LoadWith和AssociateWith
4. 查询 inner join,left outer join
5. Linq to SQL中的聚合grouping having
6. LINQ to SQL查询优化,需要忧虑性能吗?
Student和Class之间是多对一关系,Student和Course之间是多对多关系。
DataContext的DeferredLoadingEnabled属性指定是否需要延时加载,其默认值为true。以Student为例,其延时加载的对象是指Class和对应的Course。设定延时加载为true时,当访问到Student实例的Class属性或者StudentCourse属性时会自动加载Class表和StudentCourse表中的数据,如下示例代码:
args) { using (var writer = new StreamWriter(WatchSqlPath, false, Encoding.UTF8)) { using (DbAppDataContext db = new DbAppDataContext()) { db.Log = writer] 当设置DataContext的DeferredLoadingEnabled属性为true时,可以直接访问关系表中的数据,我们可以看下以上代码使用到的SQL语句: SELECT TOP (1) [t0].[StudentID], [t0].[Name], [t0].[Hometown], [t0].[Gender], [t0].[Birthday], [t0].[ClassID], [t0].[WeightInKg], [t0].[HeightInCm], [t0].[Desc] AS [Desc] FROM [dbo].[Student] AS [t0] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1 SELECT [t0].[ClassID], [t0].[ClassName] FROM [dbo].[Class] AS [t0] WHERE [t0].[ClassID] = @p0 -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1
用到了两个sql语句,在我们访问到Student的Class属性时,DataContext自动去加载了Class的数据。
在有些时候可以将DeferredLoadingEnabled属性设置为false,设置为false时再直接访问Student的Class属性时将抛出空引用的异常。
有了延时加载,LoadWith方法是做什么用的呢?
MSDN上对LoadWith的解释是:通过使用 lambda 表达式检索与主目标相关的指定数据。
LoadWith不是DataContext的方法,而是DataLoadOptions的方法,可以给DataContext设定LoadOptions属性来改变DataContext加载数据的方式;换句话说是LoadOptions设定是否在select主表数据时同时用join加载关联表的数据。
假定场景:我希望在select Student表的数据时同时用一个sql将其class的属性select出来,如下代码:
args) { using (var writer = new StreamWriter(WatchSqlPath, false, Encoding.UTF8)) { using (DbAppDataContext db = new DbAppDataContext()) { db.Log = writer] 其效果和上面例子完全一样,但是执行的SQL却是不一样的,我们看下SQL: SELECT TOP (1) [t0].[StudentID], [t0].[Name], [t0].[Hometown], [t0].[Gender], [t0].[Birthday], [t0].[ClassID], [t0].[WeightInKg], [t0].[HeightInCm], [t0].[Desc] AS [Desc], [t1].[ClassID] AS [ClassID2], [t1].[ClassName] FROM [dbo].[Student] AS [t0] INNER JOIN [dbo].[Class] AS [t1] ON [t1].[ClassID] = [t0].[ClassID] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1
这次执行只用了一个SQL语句,Student表inner join Class表,这就是LoadWith的意义所在。
LoadWith可以用一个sql语句加载相关表的数据,那么AssociateWith 方法又是做什么用的呢?
还是假定一个场景,我们想知道某个班级的信息和这个班级中体重大于30公斤的学生的信息,也就是说在取得关联表数据时附加了条件,请看下面的代码及注释:
args) { using (var writer = new StreamWriter(WatchSqlPath, false, Encoding.UTF8)) { using (DbAppDataContext db = new DbAppDataContext()) { db.Log = writer] 同样看下代码执行的真实SQL语句: SELECT [t0].[ClassID], [t0].[ClassName] FROM [dbo].[Class] AS [t0] WHERE [t0].[ClassID] = @p0 -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1 SELECT [t0].[StudentID], [t0].[Name], [t0].[Hometown], [t0].[Gender], [t0].[Birthday], [t0].[ClassID], [t0].[WeightInKg], [t0].[HeightInCm], [t0].[Desc] AS [Desc] FROM [dbo].[Student] AS [t0] WHERE ([t0].[WeightInKg] > @p0) AND ([t0].[ClassID] = (( SELECT [t2].[ClassID] FROM ( SELECT TOP (1) [t1].[ClassID] FROM [dbo].[Class] AS [t1] WHERE [t1].[ClassID] = @p1 ) AS [t2] ))) -- @p0: Input Float (Size = -1; Prec = 0; Scale = 0) [30] -- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [1] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1
可以看到是两个sql语句,第二个sql语句中AssociateWith起了作用,第一个条件是体重大于@p0,第二个条件是classID;可以看到这儿生成的sql语句很不好,ClassID是唯一主键,按理说DataContext已经知道这事儿,但是在生成语句时还是用了嵌套的查询,可以说是LINQ to SQL的一个败笔。
linq to sql相关随笔:
1. 从CUD开始,如何使用LINQ to SQL插入、修改、删除数据
2. 查询 使用LINQ to SQL做简单查询
3. 查询 延迟加载与立即加载,使用LoadWith和AssociateWith
4. 查询 inner join,left outer join
5. Linq to SQL中的聚合grouping having
6. LINQ to SQL查询优化,需要忧虑性能吗?
相关文章推荐
- LINQ to SQL系列三 使用DeferredLoadingEnabled,DataLoadOption指定加载选项
- 使用LinqToSql加载动态column
- 步步为营VS 2008 + .NET 3.5(13) - DLINQ(LINQ to SQL)之用户自定义函数、在不同的DataContext之间做更新、缓存、获取信息、数据加载选项和延迟加载
- (LINQ 学习系列)(1)使用 LINQ to SQL 的典型步骤
- LINQ to SQL系列四 使用inner join,outer join
- LINQ – 使用DataLoadOptions 提高LINQ to SQL 查询性能
- LINQ to SQL系列 查询 使用LINQ to SQL做简单查询
- 步步为营VS 2008 + .NET 3.5(13) - DLINQ(LINQ to SQL)之用户自定义函数、在不同的DataContext之间做更新、缓存、获取信息、数据加载选项和延迟加载
- LINQ to SQL 系列 如何使用LINQ to SQL插入、修改、删除数据[转]
- Linq to sql:DataLoadOptions 限制
- LINQ to SQL 系列 如何使用LINQ to SQL插入、修改、删除数据
- LINQ to SQL 系列 如何使用LINQ to SQL插入、修改、删除数据
- LINQ to SQL 系列 如何使用LINQ to SQL插入、修改、删除数据
- LINQ to SQL 系列 如何使用LINQ to SQL插入、修改、删除数据
- LINQ to SQL 系列 如何使用LINQ to SQL插入、修改、删除数据
- LINQ to SQL系列 查询 使用LINQ to SQL做简单查询
- LINQ to SQL 系列 如何使用LINQ to SQL插入、修改、删除数据
- (LINQ 学习系列)(1)使用 LINQ to SQL 的典型步骤
- LINQ to Sql系列三 延迟加载
- 步步为营VS 2008 + .NET 3.5(13) - DLINQ(LINQ to SQL)之用户自定义函数、在不同的DataContext之间做更新、缓存、获取信息、数据加载选项和延迟加载