zoukankan      html  css  js  c++  java
  • SharePoint服务器端对象模型 之 使用LINQ进行数据访问操作(Part 4)

    (六)高效合理的使用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 Framework (SPFx) 开发入门教程
    SharePoint 2013 Designer 入门教程
    SharePoint 2013 开发教程
    SharePoint 2013 入门教程
    SharePoint Online 部署SPFx Web部件
    SharePoint Online SPFx Web部件绑定数据
    SharePoint Online 创建SPFx客户端Web部件
    SharePoint Online 配置框架(SPFx)开发环境
    SharePoint Online 创建应用程序目录
    SharePoint Online 启用 IRM
  • 原文地址:https://www.cnblogs.com/erucy/p/5224845.html
Copyright © 2011-2022 走看看