在SharePoint中,我們經常要對List進行操作,比如要從List中取出相應的ListItem,利用CAML是個好辦法。在沒了解CAML之前,我是這樣取數據的:
MyList.Items.Cast<SPListItem>().ToList().Where(Condition).Select(Fields);
原諒我當初如此放盪不羈的寫法吧。
- 好了,現在進入CAML實戰中,首先CAML (Collaborative Application Markup Language)基於XML的一種語言。所以你寫CAML時一定要注意Tag是否閉合,另外CAML也是區分大小寫的。
正巧在看蝙蝠俠,可以將SPList對象可以看成是銀行,SPListItem對象可那么以看成銀行庫里一排排保險櫃,SPListItem的Fields就代表每一個保險櫃中的存放的財富(比如黃金、鑽石、美元)。所以可以把CAML比作型號各式的子彈的話,那SharePoint SPQuery對象就是蝙蝠俠中的小丑,在搶銀行之前必須把子彈上膛,對,SPQuery對象的Query屬性就是一把可以匹配任何子彈萬能武器,ViewFields就是你要搶的財富類型(黃金、鑽石、美元),RowLimit就是搶得一定數量的財富就跑路了,而返回的SPListItemCollection集合就是搶到的財富。
是不是感到很暈,沒事,先有個概念即可。我以一個簡單入門的例子,你就會明白了,當然我的比喻也是即興發揮的,有不妥也別見怪。
CAML In Action
首先我准備兩個List,一個Employee,一個Specialization,為我們提供測試數據,其中Employee中的Specialization列是查閱項類型,引用了Specialization List的數據。
- Employee
- Specializaion
現在如果想在Employee List中取出Specialization包括CSS,並且Age大於20歲,並且還是女性的Employees。
這時你腦海中的邏輯表達式為:Specialization=CSS And Age>20 And IsMale=False。
接着你需要把上述的邏輯表達式轉換為CAML語言,如下:
任何給定的And元素只能有2個結合體,即只能由2個字元素,如果需要結合3個或者更多的And條件,則必須以一個條件的形式嵌套在父And中,依次類推下去。
- 當查詢時,免不了要對結果進行排序等,這時OrderBy就可用上,比如我要對上述結果進行以Age降序形式排序,則CAML:
<OrderBy> <FieldRef Name='Age' Ascending ='False'/> </OrderBy>
- 所以完整的查詢部分CAML如下:
<Where> <And> <And> <Eq> <FieldRef Name='Specialization'/> <Value Type='Lookup'>CSS</Value> </Eq> <Gt> <FieldRef Name='Age'/> <Value Type='Number'>20</Value> </Gt> </And> <Eq> <FieldRef Name='IsMale'/> <Value Type='Integer'>0</Value> </Eq> </And> </Where> <OrderBy> <FieldRef Name='Age' Ascending ='False'/> </OrderBy>
- 當然,你可以指定從查詢中返回的Fields,SPQuery對象的ViewFields屬性就是代表從查詢中返回的Fields:
query.ViewFields = "<FieldRef Name='Title'/><FieldRef Name='Age'/>";
- 當數據量過多時,也可以限制返回的行數:
query.RowLimit = 1000;
- 所以完整的利用CAML進行查詢的代碼如下:
SPList spList = spWeb.Lists.TryGetList("Employee"); if (spList != null) { SPQuery query = new SPQuery(); query.Query = @" <Where> <And> <And> <Eq> <FieldRef Name='Specialization'/> <Value Type='Lookup'>CSS</Value> </Eq> <Gt> <FieldRef Name='Age'/> <Value Type='Number'>20</Value> </Gt> </And> <Eq> <FieldRef Name='IsMale'/> <Value Type='Integer'>0</Value> </Eq> </And> </Where> <OrderBy> <FieldRef Name='Age' Ascending ='False'/> </OrderBy> ";
query.ViewFields = "<FieldRef Name='Title'/><FieldRef Name='Age'/>"; query.RowLimit = 10; var listItemsColl = spList.GetItems(query);
- 最后感興趣的朋友可以通過調試看一下最終生成的CAML:以View開頭,而我們寫的查詢條件被包含在Query節點下:
接下來
這篇博客沒有過多的去講什么是CAML以及CAML的查詢元素,而是以一個Example展示了如何用CAML從List中獲取相應的ListItemCollection,接下來的一篇博客會對CAML語法進行一個快速參考。