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

(一)概述

在SharePoint的开发应用中,查询是非常常用的一种手段,根据某些筛选、排序条件,获得某个列表或者某一些列表中相应的列表条目的集合。

除去列表上的查询之外,在SharePoint中还大量存在着各种各样的查询,比如针对回收站的SPRecycleBinQuery、针对审计的SPAuditQuery、针对变更的SPChangeQuery等等,不过这些查询在实际项目中使用到的频率并不是很高。本章节还是着重介绍列表查询功能。

在SharePoint 2010之前,列表查询的查询语句都是通过CAML这样一种XML格式来编写的。对于开发人员来讲,准确快速地编写出较为复杂的CAML查询并非是一件轻而易举的事情,但是使用CAML进行数据查询仍是SharePoint开发中不可或缺的技能。本节将介绍如何使用CAML进行列表查询和跨多个列表之间的查询,在下一节中将介绍SharePoint 2010新引入的列表查询方式——LINQ。

 

(二)CAML查询字符串

在列表查询中,所有的查询条件都要使用一种Xml形式的语法进行描述,这种Xml语法被称作CAML(Collaborative Application Markup Language),是SharePoint中一种特定的Xml语法。实际上,在SharePoint中不仅是列表查询使用了CAML,在网站、列表、字段、内容类型、网站功能等各种对象的定义中,也大量使用了CAML格式的Xml。

CAML查询字符串总的来说可以分为3大部分:筛选条件、排序和分组条件、返回字段。

在编写CAML字符串的时候,需要特别注意Xml标签的大小写是敏感的。

 

1、筛选条件

使用CAML格式的筛选条件可以理解为是将传统的数据库中的SELECT语句以Xml的形式进行标准化,便于计算机的解析和阅读。

CAML格式的筛选条件使用<Where></Where>作为最外层结点,标志筛选条件的范围。筛选条件可以由若干个子筛选条件组成,每个子筛选条件的格式都类似于:

<操作符><字段/></></操作符> 相当于: [字段] [操作符] []

其中操作符部分一般应用中包括:Eq(等于)、Neq(不等于)、Lt(小于)、Leq(小于等于)、Gt(大于)、Geq(大于等于)、Contains(包含)、BeginsWith(以某字符串开头)、In(在集合范围内)、IsNull(为空)、IsNotNull(不为空)、Membership(属于用户组)。最后三个操作符是一元操作符,没有其中的“值”的部分。

字段部分的格式为:<FieldRef Name="字段名其他属性 />,特别注意不要遗忘最后的“/”终结符,字段名必须使用内部名称

值部分的格式为:<Value Type="类型"></Value>,其中类型部分根据不同的字段有不同的设置,常用的包括Text(文本)、Number(数值)、DateTime(日期)、Lookup(查阅项)等等。

例如,我们要在列表中查询“标题”字段(内部名称为Title)包含字符串“对象模型”的那些列表条目,如果是传统的T-SQL语句写法,应该是形如:

   1: SELECT * FROM xxList WHERE 标题 Contains '对象模型'

但是在SharePoint中,使用CAML格式描述后,就变成了:

   1: <Where>
   2:   <Contains>
   3:     <FieldRef Name='Title' />
   4:     <Value Type='Text'>对象模型</Value>
   5:   </Contains>
   6: </Where>

从查询条件的格式中可以看出,SharePoint在进行列表查询的时候,只支持字段与值的比较,而不支持两个字段之间的比较,这是一个较大的限制。

 

2、一些特殊的筛选条件

这里列出一些比较特殊的筛选条件的写法(均省略其中的Where标签):

(1)包含在集合范围内的查询,这是SharePoint 2010新增加的一种查询类型,使用“In”操作符来查询包含在指定范围内的集合。例如下面的例子查找了Writer包含在[“Erucy”, “Windie”]集合的章节(即Writer等于Erucy或Windie的章节):

 

   1: <In>
   2:   <FieldRef Name='Writer'/>
   3:   <Values>
   4:     <Value Type='Text'>Erucy</Value>
   5:     <Value Type='Text'>Windie</Value>
   6:   </Values>
   7: </In>

(2)“是/否”类型的查询,该类型在数据库中实际上是bool类型,在查询的时候使用“1”表示“是”,使用“0”表示“否”,例如:

   1: <Eq>
   2:   <FieldRef Name='BoolField'/>
   3:   <Value Type='Boolean'>1</Value>
   4: </Eq>

(3)某个人员和组类型的字段等于当前用户,如果是多选的话其中包含当前用户:

   1: <Eq>
   2:   <FieldRef Name='UserField'/>
   3:   <Value Type='Integer'><UserID/></Value>
   4: </Eq>

(4)如果某个“用户或用户组”类型的字段填写的是用户组,筛选用户组包含当前用户的:

   1: <Membership Type='CurrentUserGroups'>
   2:   <FieldRef Name='UserField'/>
   3: </Membership>

(5)默认情况下,对于时间和日期类型的查询只精确到日期,如果需要精确到时间:

   1: <Gt>
   2:   <FieldRef Name='DateTimeField' />
   3:   <Value Type='DateTime' IncludeTimeValue='TRUE'>
   4:     2009-10-08T17:48:37Z
   5:   </Value>
   6: </Gt>

(其中的日期格式可以通过使用一个静态方法SPUtility.CreateISO8601DateTimeFromSystemDateTime转换得到)

(6)一般情况下,进行查阅项或用户筛选的时候,可以使用Text类型的Value,判断查阅的列表条目的文本或用户的现实名称的字符串;如果需要精确按照被查阅条目的ID或用户的ID进行查找的话(对于多选查阅项和多选用户也应使用Eq操作符,而不是Contains操作符):

   1: <Eq>
   2:   <FieldRef Name='LookupField' LookupId='TRUE'/>
   3:   <Value Type='Lookup'>37</Value>
   4: </Eq>

(7)在日历模板类型的列表中,当需要查询某个指定时间范围内的事件的时候,如果是通过Gt/Geq和Lt/Leq方式查找,仅能查找到非重复事件,以及重复事件的第一次事件,为了能够准确地查找某个范围内的重复事件,需要使用DateRangesOverlap查询操作符,并配合SPQuery的一些属性进行。(在跨列表查询中不支持重复事件)

   1: <DateRangesOverlap>
   2:   <FieldRef Name='EventDate' />
   3:   <FieldRef Name='EndDate' />
   4:   <FieldRef Name='RecurrenceID' />
   5:   <Value Type='DateTime'>
   6:     <Today />
   7:   </Value>
   8: </DateRangesOverlap>

 

 

 

 

 

 

DateRangesOverlap操作符的写法相对比较固定,其中的EventDate是“开始时间”的内部名称;EndDate是“结束时间”的内部名称;RecurrenceID是某个和重复事件相关字段的内部名称。Value中的标签定义了查询的范围,包含如下4种:<Today/>(天)、<Week/>(周)、<Month/>(月)、<Year/>(年)。

查询的时候需要配合使用SPQuery的两个属性:ExpandRecurrence(bool类型)需要设置为true,表示查询的时候展开重复事件(即使没有重复事件,在使用操作符DateRangesOverlap的时候也应当设置此属性);CalendarDate(DateTime类型),设置查询范围的日期。例如,下面的程序查询了明天的所有事件(我们可以先提前了解一下SPQuery的使用):

   1: using(SPSite site = new SPSite("http://sp2010/book"))
   2: {
   3:   using(SPWeb web = site.OpenWeb())
   4:   {
   5:     SPList calList = web.Lists["日历"];
   6:     SPQuery query = new SPQuery();
   7:     query.ExpandRecurrence = true;
   8:     query.CalendarDate = DateTime.Today.AddDays(1);
   9:     query.Query = "<DateRangesOverlap>" +
  10:             "<FieldRef Name='EventDate' />" +
  11:             "<FieldRef Name='EndDate' />" +
  12:             "<FieldRef Name='RecurrenceID' />" +
  13:             "<Value Type='DateTime'><Today /></Value>" +
  14:             "</DateRangesOverlap>";
  15:     SPListItemCollection tomorrowEvents = list.GetItems(query);
  16:     foreach(SPListItem event in tomorrowEvents)
  17:       Console.WriteLine(event.Title);
  18:   }
  19: }

对于其他类型的查询条件,可以参考SDK中的相关章节(在英文版的SDK中,CAML查询参考的位置在:SharePoint Foundation 2010 General Reference – Services References – SharePoint Schema References – CAML Core Schemas – Query Schema)。

 

3、筛选条件中的逻辑运算

在CAML中也支持多个查询条件的逻辑组合,支持“与”和“或”,但是不支持“非”。通过<And></And>和<Or></Or>标签(注意大小写)进行逻辑运算。

不过需要特别声明的是,And标签和Or标签内部,只能使用两个查询条件。例如如下的查询条件是非法的(Cond表示每个子查询条件):

   1: <Where>
   2:   <And>
   3:     <Cond1/><Cond2/><Cond3/>
   4:   </And>
   5: </Where>

应当写成:

   1: <Where>
   2:   <And>
   3:     <And>
   4:       <Cond1/><Cond2/>
   5:     </And>
   6:     <Cond3/>
   7:   </And>
   8: </Where>

通过这种方式来保证每个逻辑运算标签内,有且仅有两个子条件。

当然,And标签和Or标签可以进行交替使用,组成复杂的逻辑筛选条件。

 

4、排序条件

在CAML查询中,使用<OrderBy></OrderBy>指定0至多组排序条件。

查询条件中每个字段按照排列的顺序依次为首要查询条件、次要查询条件、第三查询条件等等,其中每个查询条件的写法为:

   1: <FieldRef Name='字段名' Ascending='TRUE|FALSE' />

 

 

其中的Name属性同样必须使用内部名称,Ascending属性指定是否是正向排序(从小到大),如果不包含该属性,则默认为正向排序。

例如,下面的CAML片段指定了查询的排序条件为先按照作者(内部名称为Author)再按照创建时间由新到旧(内部名称为Created)进行排序:

   1: <OrderBy>
   2:   <FieldRef Name='Author'/>
   3:   <FieldRef Name='Created' Ascending='FALSE' />
   4: </OrderBy>

 

5、返回字段(栏)

进行查询的时候,并非每次都要返回条目的所有字段,出于性能考虑,可以只返回所需要的一些字段,通过制定返回字段来实现这一点,指定返回字段的方式使用<FieldRef Name='字段名' />的形式。

例如,如果需要返回标题、作者和创建时间三个字段,则写法为:

   1: <FieldRef Name='Title' />
   2: <FieldRef Name='Author' />
   3: <FieldRef Name='Created' />

这里同样需要使用字段的内部名称。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439256.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode240、剑指offer04】二维数组中的查找(线性做法)

在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右递增的顺序排序&#xff0c;每一列都按照从上到下递增的顺序排序。请完成一个高效的函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该整数。 示例: 现有矩阵 matrix 如下&#x…

【转】4.2SharePoint服务器端对象模型 之 使用CAML进行数据查询(Part 2)

&#xff08;三&#xff09;使用SPQuery进行列表查询 1、概述 列表查询主要是指在一个指定的列表&#xff08;或文档库&#xff09;中按照某些筛选、排序条件进行查询。列表查询主要使用SPQuery对象&#xff0c;以及SPList的GetItems方法&#xff0c;将SPQuery作为参数传递&a…

剑指 Offer 51. 数组中的逆序对(归并排序做法)

在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组&#xff0c;求出这个数组中的逆序对的总数。 示例 1: 输入: [7,5,6,4] 输出: 5 限制&#xff1a; 0 < 数组长度 < 50000 来源&#xff1a;力扣…

【转】4.3SharePoint服务器端对象模型 之 使用CAML进行数据查询(Part 3)

&#xff08;四&#xff09;使用SPSiteDataQuery进行多列表查询 1、概述 前面介绍的列表查询有很多优势&#xff0c;但是它的一个缺点就是一次只能在一个列表中进行查询&#xff0c;在SharePoint中&#xff0c;提供了一个跨网站、跨列表查询的机制。通过使用SPSiteDataQuery对…

【LeetCode1046】最后一块石头的重量(堆heap)

题干&#xff1a; 有一堆石头&#xff0c;每块石头的重量都是正整数。 每一回合&#xff0c;从中选出两块 最重的 石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结果如下&#xff1a; 如果 x y&#xff0c;那么…

一步步编写操作系统 49 加载内核2

内核文件kernel.bin是elf格式的二进制可执行文件&#xff0c;初始化内核就是根据elf规范将内核文件中的段&#xff08;segment&#xff09;展开到&#xff08;复制到&#xff09;内存中的相应位置。在分页模式下&#xff0c;程序是靠虚拟地址来运行的&#xff0c;无论是内核还是…

【牛客 - NC93】设计LRU缓存结构(模拟)

设计LRU缓存结构_牛客题霸_牛客网 描述 设计LRU(最近最少使用)缓存结构&#xff0c;该结构在构造时确定大小&#xff0c;假设大小为 k &#xff0c;并有如下两个功能 1. set(key, value)&#xff1a;将记录(key, value)插入该结构 2. get(key)&#xff1a;返回key对应的val…

【转】理解SQL Server的安全对象和权限

理解安全对象(Securable) 安全对象&#xff0c;是SQL Server 数据库引擎授权系统控制对其进行访问的资源。通俗点说&#xff0c;就是在SQL Server权限体系下控制的对象&#xff0c;因为所有的对象(从服务器&#xff0c;到表&#xff0c;到视图触发器等)都在SQL Server的权限体系…

【LeetCode 986】 区间列表的交集(区间交集)

给定两个由一些 闭区间 组成的列表&#xff0c;firstList 和 secondList &#xff0c;其中 firstList[i] [starti, endi] 而 secondList[j] [startj, endj] 。每个区间列表都是成对 不相交 的&#xff0c;并且 已经排序 。 返回这 两个区间列表的交集 。 形式上&#xff0c…

【转】SQL Server服务器名称与默认实例名不一致的修复方法

服务器级的urn筛选器无效&#xff1a;筛选器必须为空&#xff0c;或服务器属性必须等于实际的服务器名称 这个问题是出在本地连接还是远程连接上&#xff0c;这个问题可能是由于修改过服务器名称导致的。你可以尝试在本地的服务器和SQL Server上运行以下指令&#xff0c;看看服…

【LeetCode 295】. 数据流的中位数

中位数是有序列表中间的数。如果列表长度是偶数&#xff0c;中位数则是中间两个数的平均值。 例如&#xff0c; [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 3) / 2 2.5 设计一个支持以下两种操作的数据结构&#xff1a; void addNum(int num) - 从数据流中添加一个整数到…

【转】如何从SharePoint Content DB中查询List数据***

SharePoint用来维护基础数据非常方便&#xff0c;只需要建立自定义列表&#xff0c;然后使用InfoPath自定义一下维护界面&#xff0c;就可以实现在线的增删改查&#xff0c;开发效率很高。如果维护的数据需要进行审批&#xff0c;还可以加入工作流功能。使用SharePoint Designe…

【搬石头排序】

据说是2020浪潮笔试 时间限制&#xff1a;C / C 语言 1000 MS&#xff1b;其他语言 3000 MS 内存限制&#xff1a;C / C 语言 131072 KB&#xff1b;其他语言 655360 KB 题目描述&#xff1a; 沙滩按照线型摆放着n个大小不一的球形石头&#xff0c;已知第i个石头的半径为ri&a…

【转】SharePoint Content Database简介

SharePoint作为微软主打的企业Portal平台&#xff0c;功能强大&#xff0c;使用简单&#xff0c;非常的方便。对于很多关系数据&#xff0c;我们可以使用自定义列表来维护&#xff0c;如果是非关系数据&#xff0c;可以使用文档库来维护。另外还可以在上面进行版本维护&#xf…

【LeetCode 2】两数相加(链表)

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

软件测试几个概念 --dev sit uat

DEV环境&#xff1a;DEV顾名思义就是develop&#xff0c;即代码开发的环境。 SIT环境&#xff1a;System Integration Test系统集成测试&#xff0c;开发人员自己测试流程是否走通。 UAT环境&#xff1a;User Acceptance Test用户验收测试&#xff0c;由专门的测试人员验证&…

【LeetCode 629】K个逆序对数组

给出两个整数 n 和 k&#xff0c;找出所有包含从 1 到 n 的数字&#xff0c;且恰好拥有 k 个逆序对的不同的数组的个数。 逆序对的定义如下&#xff1a;对于数组的第i个和第 j个元素&#xff0c;如果满i < j且 a[i] > a[j]&#xff0c;则其为一个逆序对&#xff1b;否则…

VSTS TFS 强制删除签出锁定项 解除 锁定

项目组一哥们走的时候以独占方式迁出了文件&#xff0c;现在其他人都无法修改&#xff0c;管理员似乎也无法将文件解除。经过摸索&#xff0c;找到了一种暴力的方法——直接改数据库。虽然暴力&#xff0c;却能实实在在地解决这个问题。 步骤&#xff1a; 1、连接到TFS数据库…

【NC30】缺失的第一个正整数

描述 给定一个无重复元素的整数数组nums&#xff0c;请你找出其中没有出现的最小的正整数 进阶&#xff1a; 空间复杂度 O(1)&#xff0c;时间复杂度 O(n) 数据范围: -2^31<nums[i]<2^31-1 0<len(nums)<5*10^5 示例1 输入&#xff1a; [1,0,2] 复制返回值…

【NC140 排序】手写快速排序

描述 给定一个长度为 n 的数组&#xff0c;请你编写一个函数&#xff0c;返回该数组按升序排序后的结果。 数据范围&#xff1a; 0 \le n \le 1\times10^30≤n≤1103&#xff0c;数组中每个元素都满足 0 \le val \le 10^90≤val≤109 要求&#xff1a;时间复杂度 O(n^2)O(n2)…