【转】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' />這里同樣需要使用字段的內部名稱。
總結
以上是生活随笔為你收集整理的【转】4.SharePoint服务器端对象模型 之 使用CAML进行数据查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个体户网上申请信用卡安全吗
- 下一篇: 各国的国家债务占GDP比重,美国为123