- SharePoint 2013 應用開發實戰
- 劉中正
- 1929字
- 2021-03-26 18:51:21
2.6 CAML和列表查詢對象
前面的章節中介紹了如何通過對象模型獲取列表的數據,但是在現實的環境中,一個列表的列表項數量可能是非常龐大的,如果通過SPList.Items的方式獲取列表數據,是很低效的一種手段。在SQL數據庫中,可以通過執行SQL查詢語句來篩選數據,類似的,在SharePoint服務器端對象模型中,可以使用SPQuery對象、SPSiteDataQuery對象或LINQ to SharePoint提供程序來達到類似篩選的效果。
2.6.1 CAML
在介紹它們之前,先了解一下CAML的概念。
協作應用程序標記語言簡稱CAML,它是基于XML的,用來定義SharePoint網站和列表中的欄和視圖,大小寫敏感。它可以用來定義數據、呈現數據并在編程中使用。
讀者可以參照SQL查詢語句進行學習,CAML在查詢中用到的內容相當于SQL語句中where之后的部分。通常一個完整的查詢框架格式為下面所示樣式結構:
<Where> <And|Or> <Oper> … </Oper> </And|Or> </Where> <GroupBy>…</GroupBy> <Orderby></OrderBy> <ViewFields></ViewFields> <RowLimit></RowLimit>
條件運算符有And和Or,分別是并且和或者的意思。這里有一點需要注意,一個條件運算符至多只能包含兩個操作運算符,超過是無效的。舉例來說,當有三個操作Oper1、Oper2和Oper3是并且關系時,正確的寫法是:
<Where> <And> <And> <Oper1> </Oper1> <Oper2> </Oper2> </And> <Oper3> </Oper3> </And> </Where>
常用的比較運算符如表2-1所示。
表2-1 常用的CAML比較運算符

讀者可以訪問https://msdn.microsoft.com/zh-cn/library/ms467521.aspx查看最新的運算符說明。
2.6.2 SPQuery和SPSiteDataQuery對象
SPQuery對象模型用來在查詢列表數據時構建一個查詢條件,返回滿足條件的列表項的集合。還是以前面章節的自定義列表為例,下面的代碼展示了如何查詢列表項中標題欄包含A的列表項的集合:
using (SPSite site = new SPSite("http://<mysiteurl>/subSite")) { using (SPWeb web = site.OpenWeb()) { SPList customList = web.GetList("/Lists/List/"); SPQuery query = new SPQuery(); query.Query = @"<Where> <Contains> <FieldRef Name='Title' /> <Value Type='TEXT'>A</Value> </Contains> </Where>"; query.RowLimit = 10; SPListItemCollection queryItems = customList.GetItems(query); foreach (SPListItem item in queryItems) { Console.WriteLine(string.Format("Item Title: {0}", item.Title)); } } }
執行結果將只輸出自定義列表中標題包含A的列表項。
SPQuery只能在單一列表內進行使用,如果想在網站集的范圍內查詢某一類型多個列表項數據,就需要用到SPSiteDataQuery對象了。筆者在網站中新建另一個自定義列表來演示該對象的用法,在新的自定義列表中新建一個列表項叫做A+,如圖2-21所示。

圖2-21 新的自定義列表
現在需要查詢出SharePoint網站的所有自定義列表中列表項標題包含A的集合,代碼如下所示:
using (SPSite site = new SPSite("http://<mysiteurl>/subSite")) { using (SPWeb web = site.OpenWeb()) { SPSiteDataQuery siteQuery = new SPSiteDataQuery(); siteQuery.Lists = "<Lists ServerTemplate=\"100\" />"; siteQuery.ViewFields = "<FieldRef Name=\"Title\" />"; siteQuery.Query = @"<Where> <Contains> <FieldRef Name='Title' /> <Value Type='TEXT'>A</Value> </Contains> </Where>"; DataTable dataTable = web.GetSiteData(siteQuery); foreach (DataRow dataRow in dataTable.Rows) { Console.WriteLine(string.Format("Item Title: {0}", dataRow["Title"])); } } }
其中SPSiteDataQuery.Lists屬性指定了要查詢哪一類列表,這么寫是因為自定義列表的模板ID為100。在SharePoint中,不同類型的列表具有不同的模板ID,讀者可以通過在網站上添加列表→高級選項時通過查看瀏覽器的URL得到這個模板ID,如圖2-22所示。

圖2-22 自定義列表的模板ID
執行結果將輸出“公告A”和“A+”,如圖2-23所示。

圖2-23 SPSiteDataQuery執行的輸出結果
雖然CAML語句比較容易理解,但是跟SQL語句相比,尤其是查詢條件復雜時,是很容易出錯的,筆者建議盡量使用CAML工具(如CAML Designer、CAML Builder)來構建CAML查詢語句。
2.6.3 LINQ to SharePoint
查詢列表數據的另一種方式是使用LINQ語法查詢SharePoint列表。LINQ to SharePoint是始于SharePoint 2010的新特性,它使用類型化的方式訪問列表,類似訪問數據庫,更容易被習慣和接受。
LINQ to SharePoint的本質仍然是利用CAML查詢,LINQ to SharePoint提供的程序是在Microsoft.SharePoint.Linq命名空間中被定義,它會自動將LINQ轉換成CAML查詢。所以,開發人員無須再去了解如何編寫CAML查詢語句,提升了開發人員的效率。
使用LINQ to SharePoint可以實現列表項的增刪改查操作,筆者推薦使用實體類生成工具SPMetal生成SharePoint網站中列表的實體類,雖然可以手寫實體類,但這畢竟增大了出錯的幾率,而且操作起來較為煩瑣。有高效的手段,何樂而不為呢?
學習這部分時,讀者可以類比Entity Framework,它們的共性是都根據現有數據生成實體類以方便開發人員做處理。
SPMetal工具位于SharePoint服務器的C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\BIN目錄下,如圖2-24所示。

圖2-24 SPMetal工具的物理路徑
使用如下操作可以生成網站的內容實體模型:
(1)以管理員身份運行命令提示符,輸入cd C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\BIN進入到SPMetal工具所在文件夾。
(2)執行命令spmetal.exe /web:<your sharepoint site url> /code:C:\WebDataEntities.cs,執行成功后將在C盤根目錄生成實體類文件WebDataEntities.cs。
開始編寫代碼之前,首先在項目中添加Microsoft.SharePoint.Linq的引用,然后右擊項目節點,選擇添加→現有項,選擇生成的CS文件添加到項目中。
準備工作完成了,下面將通過代碼帶領讀者一步一步了解如何利用LINQ to SharePoint實現基本操作,還是以網站中的自定義列表為例。
獲取列表項并輸出的代碼如下所示:
using (WebDataEntitiesDataContext ctx = new WebDataEntitiesDataContext("http://<mysiteurl>/subSite")) { var items = ctx.自定義列表.Where(p=>p.標題.Contains("A")).ToList(); foreach (自定義列表項目 item in items) { Console.WriteLine(string.Format("Item Title: {0}.", item.標 題)); } }
運行結果和之前的一樣,由于筆者使用的是中文的環境,而SPMetal工具根據名稱生成相應的實體類,所以代碼中出現了中文。
添加、修改、刪除列表項的代碼如下所示。
添加列表項:
using (WebDataEntitiesDataContext ctx = new WebDataEntitiesDataContext("http://<mysiteurl>/subSite")) { 自定義列表項目 newItem = new 自定義列表項目(); newItem.標題 = "公告C"; newItem.公告內容 = "公告C的內容"; ctx.自定義列表.InsertOnSubmit(newItem); ctx.SubmitChanges(); }
修改列表項:
using (WebDataEntitiesDataContext ctx = new WebDataEntitiesDataContext("http://<mysiteurl>/subSite")) { 自定義列表項目 itemToModify = ctx.自定義列表.Where(p => p.Id == 5).FirstOrDefault(); if (itemToModify!= null) { itemToModify.標題="公告C改"; itemToModify.公告內容 = "公告C的內容改"; } ctx.SubmitChanges(); }
刪除列表項:
using (WebDataEntitiesDataContext ctx = new WebDataEntitiesDataContext("http://<mysiteurl>/subSite")) { 自定義列表項目 itemToDelete = ctx.自定義列表.Where(p => p.Id == 5).FirstOrDefault(); if (itemToDelete != null) { ctx.自定義列表.DeleteOnSubmit(itemToDelete); } ctx.SubmitChanges(); }
以上便是LINQ to SharePoint在應用上的基本操作實例,尤其是查詢部分,比SPQuery的CAML查詢要靈活簡便得多,推薦使用這種方式進行列表的查詢等操作。在使用時要注意數據結構的一致性,否則可能會導致異常錯誤。
- Linux設備驅動開發詳解:基于最新的Linux4.0內核
- 發布!設計與部署穩定的分布式系統(第2版)
- 蘋果電腦玩全攻略 OS X 10.8 Mountain Lion
- Persistence in PHP with the Doctrine ORM
- Learn Helm
- 循序漸進學Docker
- Linux內核設計的藝術:圖解Linux操作系統架構設計與實現原理
- 跟老男孩學Linux運維:Shell編程實戰
- CentOS 6 Linux Server Cookbook
- Windows 7使用詳解(修訂版)
- Android NDK Beginner's Guide
- Responsive Web Design with AngularJS
- Gradle Effective Implementations Guide(Second Edition)
- 從零開始學Windows 7
- 蘋果派