(六)高效合理的使用LINQapp
一、DataContext中的两个属性ide
为了可以使用DataContext进行数据提交,在DataContext进行数据查询和操做的过程当中,内部会进行数据状态的保持和追踪,这会带来一些额外的开销。若是用户仅须要进行数据读取的话,能够经过将DataContext的ObjectTrackingEnabled属性设为false(默认值为true)来避免这些维护数据状态带来的额外开销。工具
此外,在DataContext中还有一个DefferedLoadingEnabled属性,用于控制数据实体之间的引用(对应到SharePoint列表中即查阅项)是否加载。若是将此属性设置为false(默认值为true),那么在返回结果以后,全部的查阅项引用都不会加载,值为null。所以,若是不须要使用其中查阅项类型内容的话,能够将此属性设置为false,能够进一步提升查询速度。网站
二、LINQ中的运算spa
在针对其余数据源进行查询的时候,LINQ能够进行多种运算,可是因为在SharePoint中,查询最终是使用CAML进行的,所以有些运算在LINQ to SharePoint中是不支持的,或者在执行效率上有所区别。code
高效查询(Efficient Queries)对象
在LINQ to SharePoint中,凡是能够直接被转换成CAML查询的LINQ查询,都被称为高效查询。系统会将CAML查询的结果直接转换成相应的数据实体。ip
不支持的查询内存
在LINQ中,不支持查询嵌套,即将一个查询的结果做为另一个查询的查询条件(在传统的T-SQL中,也就是select语句的嵌套)。ci
此外,在LINQ to SharePoint中,对两个查询结果的集合操做也是不被支持的,例以下面的程序会抛出异常:
1: var orders1 = from o in ctx.InteralOrder
2: select o;
3: var orders2 = from o in ctx.ExternalOrder
4: select o;
5: var total = orders.Union(orders2); // Exception Here!
可是经过使用ToList方法将结果转换成List以后,就能够进行集合运算了:
1: var orders1 = from o in ctx.InteralOrder
2: select o;
3: var orders2 = from o in ctx.ExternalOrder
4: select o;
5: var total = orders.ToList().Union(orders2.ToList()); //OK Now.
半高效查询(Semi-Efficient Queries)
在有些状况下,查询条件能够被直接转换成CAML进行,可是在返回结果的时候,却没法转换成相应的CAML。考虑下面两个例子:
1: // 查询1:
2: var chapters = from chp in ctx.Chapters
3: where chp.Writer == "Erucy"
4: select new {chp.Name, chp.WordCount};
5:
6: // 查询2:
7: var chapters = from chp in ctx.Chapters
8: where chp.Writer == "Erucy"
9: select new {chp.Name, Pay = chp.WordCount * 0.05};
1: <Where>
2: <Eq>
3: <FieldRef Name='Writer'/>
4: <Value Type='Text'>Erucy</Value>
5: </Eq>
6: </Where>
在查询1中,查询结果能够直接用CAML的ViewFields来表示:
1: <ViewFields>
2: <FieldRef Name='Name' />
3: <FieldRef Name='WordCount' />
4: </ViewFields>
因而,LINQ to SharePoint即可以直接将返回结果转换成相应的数据实体对象。
可是在查询2中,返回结果的“WordCount * 0.05”部分因为涉及到了运算,没法直接使用CAML进行描述,所以LINQ to SharePoint在返回这类查询结果的时候,须要在CAML查询结果的基础之上,再利用LINQ to Objects进行一次结果转换,可是在转换过程当中不须要再涉及查询操做。这种查询实际上至关于以下代码:
1: var camlResult = from chp in ctx.Chapters
2: where chp.Writer == "Erucy"
3: select new {chp.Name, chp.WordCount};
4: var chapters = from chp in camlResult
5: select new {chp.Name, Pay = chp.WordCount * 0.05};
除去这种简单运算以外,在返回结果的时候,LINQ查询中所使用到的Distinct、Average、Sum、Max、Min等操做都属于这一类型。因为这种查询须要两个阶段来完成,所以也被称为两阶段查询(Two-Stage Queries)。
低效查询(Inefficient Queries)
在上面的例子中,仅是在返回结果的时候须要进行额外的转换,而查询自己仍然可使用CAML进行。而在有些状况下,查询彻底没法转换成CAML格式,而这个时候,LINQ to SharePoint会首先获取到列表中全部内容,将其转换为类型,在此基础上再进行LINQ to Objects的查询,使得SharePoint数据查询彻底退化成内存中的数据查询。这种查询也须要使用两个阶段来完成操做,但因为须要获取列表中的所有数据,效率较低。
这种查询能够实现一些CAML没法实现的功能。在CAML查询中,只支持字段栏与具体数值之间的比较运算,但不支持字段栏与字段栏之间的运算,例以下面的这个查询:
1: var okOrders = from order in ctx.Orders
2: where order.Sale > order.Quota
3: select order;
1: var okOrders = from order in ctx.Orders.ToList()
2: where order.Sale > order.Quota
3: select order;
(ToList方法会将EntityList退化成普通的List,将Orders列表中的全部数据都载入内存,再进行查询)
三、LINQ to SharePoint所不支持的场景
虽然LINQ to SharePoint在进行数据查询、数据操做的时候提供了无比的便利性,可是并不是是全部场景均可以使用LINQ。除去上面提到的不支持的运算外,下面列出了几种常见的默认状况下不能使用LINQ to SharePoint的场景: