(六)高效合理的使用LINQ

1、DataContext中的两个属性

为了能够使用DataContext进行数据提交,在DataContext进行数据查询和操作的过程中,内部会进行数据状态的保持和追踪,这会带来一些额外的开销。如果用户仅需要进行数据读取的话,可以通过将DataContext的ObjectTrackingEnabled属性设为false(默认值为true)来避免这些维护数据状态带来的额外开销。

此外,在DataContext中还有一个DefferedLoadingEnabled属性,用于控制数据实体之间的引用(对应到SharePoint列表中即查阅项)是否加载。如果将此属性设置为false(默认值为true),那么在返回结果之后,所有的查阅项引用都不会加载,值为null。因此,如果不需要使用其中查阅项类型内容的话,可以将此属性设置为false,可以进一步提高查询速度。

2、LINQ中的运算

在针对其他数据源进行查询的时候,LINQ可以进行多种运算,但是由于在SharePoint中,查询最终是使用CAML进行的,因此有些运算在LINQ to SharePoint中是不支持的,或者在执行效率上有所区别。

高效查询(Efficient Queries)

在LINQ to SharePoint中,凡是可以直接被转换成CAML查询的LINQ查询,都被称为高效查询。系统会将CAML查询的结果直接转换成相应的数据实体。

不支持的查询

在LINQ中,不支持查询嵌套,即将一个查询的结果作为另外一个查询的查询条件(在传统的T-SQL中,也就是select语句的嵌套)。

此外,在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;

在实际查询的时候,由于CAML不支持在两个字段之间进行比较,因此这个查询最终会退化为在内存中的对象查询:

   1: var okOrders = from order in ctx.Orders.ToList()

   2:                where order.Sale > order.Quota

   3:                select order;

(ToList方法会将EntityList退化成普通的List,将Orders列表中的所有数据都载入内存,再进行查询)

3、LINQ to SharePoint所不支持的场景

虽然LINQ to SharePoint在进行数据查询、数据操作的时候提供了无比的便利性,但是并非是所有场景都可以使用LINQ。除去上面提到的不支持的运算外,下面列出了几种常见的默认情况下不能使用LINQ to SharePoint的场景:

  • 无法查询外部列表(External List)和外部内容类型(External Content Type)。SPMetal工具不会为这些类型的数据生成数据实体类。不过查询外部数据可以使用相应的其他类型的LINQ Provider,如LINQ to SQL、LINQ to XML等。
  • 在Web上只能查询当前网站的内容。由于在DataContext中某些地方用到了当前的上下文信息(HttpContext),因此在Web上(比如Web部件),LINQ to SharePoint默认情况下只能对当前程序所在网站的内容进行查询。
  • 不支持匿名网站。LINQ to SharePoint目前仍不支持网站的匿名访问(即使网站开启了匿名访问支持)。

SharePoint服务器端对象模型 之 使用LINQ进行数据访问操作(Part 4)的更多相关文章

  1. SharePoint 服务器端对象模型 之 使用LINQ进行数据访问操作(Part 2)

    (四)使用LINQ进行列表查询 在生成实体类之后,就可以利用LINQ的强大查询能力进行SharePoint列表数据的查询了.在传统SharePoint对象模型编程中,需要首先获取网站对象,再进行其他操 ...

  2. SharePoint服务器端对象模型 之 使用CAML进展数据查询

    SharePoint服务器端对象模型 之 使用CAML进行数据查询 一.概述 在SharePoint的开发应用中,查询是非常常用的一种手段,根据某些筛选.排序条件,获得某个列表或者某一些列表中相应的列 ...

  3. SharePoint服务器端对象模型 之 使用CAML进行数据查询

    (一)概述 在SharePoint的开发应用中,查询是非常常用的一种手段,根据某些筛选.排序条件,获得某个列表或者某一些列表中相应的列表条目的集合. 除去列表上的查询之外,在SharePoint中还大 ...

  4. SharePoint服务器端对象模型 之 使用CAML进行数据查询(Part 4)

    (五)列表查询中的阈值限制 在之前版本的SharePoint 中,如果在查询的时候没有指定返回数目,那么SharePoint将会查找该列表中所有的条目,这可能会造成在SQL表中需要返回大量的条目,极大 ...

  5. SharePoint服务器端对象模型 之 使用CAML进行数据查询(Part 2)

    (三)使用SPQuery进行列表查询 1.概述 列表查询主要是指在一个指定的列表(或文档库)中按照某些筛选.排序条件进行查询.列表查询主要使用SPQuery对象,以及SPList的GetItems方法 ...

  6. SharePoint服务器端对象模型 之 使用CAML进行数据查询(Part 3)

    (四)使用SPSiteDataQuery进行多列表查询 1.概述 前面介绍的列表查询有很多优势,但是它的一个缺点就是一次只能在一个列表中进行查询,在SharePoint中,提供了一个跨网站.跨列表查询 ...

  7. SharePoint服务器端对象模型 完结

    整个系列已完结,大概看了一眼,平均阅读量不到200.估计也没什么人看了,而且服务器端对象模型除了在某些企业开发中会用到,从2013时代开始其实已经不是SharePoint开发的最佳选择了.不过既然已经 ...

  8. SharePoint服务器端对象模型 之 序言

    对于刚刚开始接触SharePoint的开发人员,即使之前有较为丰富的ASP.NET开发经验,在面对SharePoint时候可能也很难找到入手的方向.对于任何一种开发平台而言,学习开发的过程大致会包括: ...

  9. SharePoint服务器端对象模型 之 对象模型概述(Part 2)

    (三)Url 作为一个B/S体系,在SharePoint的属性.方法参数和返回值中,大量的涉及到了Url,总的来说,涉及到的Url可以分为如下四类: 绝对路径:完整的Url,包含了协议头(http或h ...

随机推荐

  1. python selenium --browser 操作

    本节知识点: 打印URL 将浏览器最大化 设置浏览器固定宽.高 操控浏览器前进.后退 打印URL 上一节讲到,可以将浏览器的title打印出来,这里再讲个简单的,把当前URL打印出来.其实也没啥大用, ...

  2. ContentObserver与DatasetObserver区别

        1. ContentObserver ContentObserver主要是通过Uri来监测特定的Databases的表,如果该Databases表有变动则会通知更新cursor中的数据. 如果 ...

  3. myeclipse之完全破解

    并不是所有的破解都是成功的,就如并不是所有的战争都会胜利一样,我们在做事情的时候,总会遇到些问题,比如Activate不成功,需要手动激活. 激活不成功就是不成功,来回的破解.卸载.重装,都还是不可能 ...

  4. github 修改项目默认语言

    我们在提交到github上的项目有时候被识别成了其它的语言,非我们使用的语言,这个时候可以采取以下措施来强制将语言改成我们需要的语言 在项目中创建一个文件 .gitattributes 打开.gita ...

  5. Failed to resolve: com.android.support:appcompat-v7:26.0.0wenti

    在安装Android Studio 3.0的时候出现了这个问题.查阅了许多资料都没有找到原因.到最后才发现,Android Studio默认https是不走代理的,只要勾选上https的代理就顺利的安 ...

  6. 使用code::blocks搭建objective-c的IDE开发环境 支持 @interface

    网上有许多的关于 <使用code::blocks搭建objective-c的IDE开发环境>的文章. 大多是写了一个Helloworld 就结束了,今天试了试 添加了一个 @interfa ...

  7. Java反射小结

    一.什么是反射? 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法 ...

  8. nginx-1.14.0安装

    1.百度搜索Nginx,点击Nginx news官网,点击nginx-1.13.10进入下载网页,选择Stable version的版本之后下载. 2.进入根目录,cd / 3.在根目录下创建soft ...

  9. gitlab手残点错关闭注册No authentication methods configured on login page

    Gitlab - 如何解決 "No authentication methods configured on login page" ? (gitlab version : 8.1 ...

  10. 例举在诊断Oracle性能问题时,常用的工具、方法

    例举在诊断Oracle性能问题时,常用的工具.方法 解答: 1)简单一点的可以用toad及dbartisan这样的工具. 2)纯做性能监测,比较出色的有spolight和emc的I3,这两个软件都比较 ...