【转】WSS3.0开发--你还在为写CAML痛苦吗?
?
進行WSS3或MOSS開發的朋友不可避免的要處理各種List的查詢,編寫類似下面的CAML語句:
<Where><And>
?<And>
??<Eq><FieldRef?Name=”Title”><Value?Type=”Text”>Value</Value></Eq>
??<Eq><FieldRef?Name=”ContentType”><Value?Type=”Text”>Product</Value></Eq>
?</And>
?<Eq><FieldRef?Name=”Field1”><Value?Type=”Text”>Value</Value></Eq>
</And>?
<Or>
?<Or>
??<Eq><FieldRef?Name=”Title”><Value?Type=”Text”>Value</Value></Eq>
??<Eq><FieldRef?Name=”ContentType”><Value?Type=”Text”>Product</Value></Eq>
?</Or>
?<Eq><FieldRef?Name=”Field1”><Value?Type=”Text”>Value</Value></Eq>
</Or>?
</Where>
痛苦吧? 簡單的還好,復雜一點的caml查詢絕對會讓你暈頭轉向。
現在網上的解決方案有幾種:
1)CAMLBuilder:提供一個Window程序,可以動態生成CAML,然后開發人員可以粘貼進代碼代碼中。
http://blog.u2u.info/DottextWeb/patrick/archive/2005/05/29/3522.aspx
2)CAML.net : 提供了一個類庫,可以如下的編寫CAML:
http://www.codeplex.com/camldotnet
string?simpleQuery?=
????CAML.Query(
????????CAML.Where(
????????????CAML.Or(
????????????????CAML.Eq(
????????????????????CAML.FieldRef("ContentType"),?
????????????????????CAML.Value(typeName)),
????????????????CAML.IsNotNull(
????????????????????CAML.FieldRef("Description")))),
????????CAML.GroupBy(
????????????true,
????????????CAML.FieldRef("Title",CAML.SortType.Descending)),
????????CAML.OrderBy(
????????????CAML.FieldRef("_Author"),
????????????CAML.FieldRef("AuthoringDate"),
????????????CAML.FieldRef("AssignedTo",CAML.SortType.Ascending))
????);
3)還有一位兄弟寫了個支持用sql語句形式的caml類庫,查詢語句如下:
string?queryStr?=?"SELECT?*?FROM?通知?WHERE?ID>10";
FriendlyQuery?query?=?new?FriendlyQuery(web,?queryStr);
query.RowLimit?=?100;
query.Scope?=?FriendlyQuery.QueryScope.?AllItemsAndFolders;
SPListItemCollection?items?=?query.GetItems();
foreach(SPListItem?i?in?items)
????Response.Write(i.Title?+?"<br/>");
上面的三種方案,個人還是比較喜歡CAML.net的實現,純代碼,但是它的語法不是那么的"優雅"。
以前寫過一個數據庫ORM工具,見(DBO),實現了如下的數據查詢語法:
?????????????DboQuery.Select(?User.__UserName,Org.__OrgName?)
?????????????.From<User>()
?????????????.InnerJoin<Org>().On(User.__OrgId,?Org.__OrgId)
?????????????.Where(Org.__OrgId?==?2?|?Org.__OrgId?==?3);
?IList<RefOrgUser>?orgs?=?_session.Query<RefOrgUser>(expr)?;
于是,計劃開發類似語法的CAML查詢類庫--CodeArt.SharePoint.CAMLQuery.dll。
07年六月份開始開發,已經用到了實際的項目中,實現了幾個復雜的查詢功能,好東西不敢獨享,哈哈,給大家show一下。
(在后面大家可以找到dll的下載鏈接)
以下的代碼示例針對一個列表CAMLList做查詢,此列表有如下字段:標題,正文,修改時間。
首先,引用名稱空間。
using?Microsoft.SharePoint;
using?CodeArt.SharePoint.CAMLQuery;
代碼1:查詢標題中包含"XXX"的 項目:
??QueryField?titleField?=?new?QueryField("標題");? SPSite?site?=?new?SPSite("http://jyserver:9000");
? SPList?list?=??site.RootWeb.Lists["CAMLTest"];
?? SPQuery?q?=?new?SPQuery?();
?? q.Query?=?CAMLBuilder.Where(?list?,?titleField.Contains("XXX")?);
???????????
?? SPListItemCollection?items?=?list.GetItems(q);
?? int?count?=?items.Count;?????????
代碼2:查詢標題中包含"XXX"或"YYY"的 項目:
?SPList?list?=?this.GetTestList();? ICAMLExpression?expr?=?QueryModel.Title.Contains("XXX")?||?QueryModel.Title.Contains("YYY");????????????
? PQuery?q?=?new?SPQuery();
? q.Query?=?CAMLBuilder.Where(list,?expr?);
? SPListItemCollection?items?=?list.GetItems(q);
? int?count?=?items.Count;
代碼3:我們可以創建一個查詢模型,類似一個實體類,針對這個類進行查詢:
/**////?<summary>????????///?查詢模型
????????///?</summary>
????????class?QueryModel
????????{
????????????public?static?FieldRef<QueryModel>?Title?=?new?FieldRef<QueryModel>("標題");
????????????public?static?FieldRef<QueryModel>?Body?=?new?FieldRef<QueryModel>("正文");
????????????public?static?TypeFieldRef<QueryModel,?DateTime>?ModifyTime?=?new?TypeFieldRef<QueryModel,?DateTime>("修改時間");
????????}
????????[TestMethod]
????????public?void?TestModelQuery()
????????{??????????
????????????SPList?list?=?this.GetTestList();
????????????SPQuery?q?=?new?SPQuery();
????????????q.Query?=?CAMLBuilder.Where(?list?,??QueryModel.Title.Contains("XXX")?);
????????????q.ViewFields?=?CAMLBuilder.ViewFields(?list?,?QueryModel.Title,?QueryModel.Body);
????????????SPListItemCollection?items?=?list.GetItems(q);
????????????int?count?=?items.Count;
????????}
代碼4:按照邏輯動態拼接查詢,以下示例查詢標題中包含"XXX"或"YYY"的 項目,按照queryByTime 參數,附加修改時間條件:
?SPList?list?=?this.GetTestList();? bool?queryByTime?=?true?;
? TypedCAMLExpression<QueryModel> expr = QueryModel.Title.Contains("XXX") || QueryModel.Title.Contains("YYY"); ?
????????
? if(?queryByTime?)
??????? expr?=?expr?&?QueryModel.ModifyTime?>=?DateTime.Now.AddDays(-1)
?? SPQuery?q?=?new?SPQuery();
?? q.Query?=?CAMLBuilder.Where(list,?expr?);
?? SPListItemCollection?items?=?list.GetItems(q);
? int?count?=?items.Count;
代碼5:我們可以用類似sql的強類型語法:
?QueryField?titleField?=?new?QueryField("標題");QueryField?bodyField?=?new?QueryField("正文");
????????????SPList?list?=?this.GetTestList();
??? ?? ?? //只查詢兩個字段
????????????SPListItemCollection?result1?=
????????????????ListQuery.Select(titleField,?bodyField)
????????????????????????.From(list)
????????????????????????.Where(titleField.Contains("XXX"))
????????????????????????.GetItems();
????????????int?count?=?result1.Count;
??? ?? ?? //查詢所有字段
????????????SPListItemCollection?result2?=
????????????????ListQuery.From(list)
?????????????????????????.Where(titleField.Contains("XXX"))
?????????????????????????.GetItems();
????????????int?count2?=?result2.Count;
??? ?? ?? //直接返回DataTable
????????????DataTable?result3?=
????????????????ListQuery.Select(titleField,bodyField)
????????????????????????.From(list)
?????????????????????????.Where(titleField.Contains("XXX")|titleField.Contains("YYY"))
?????????????????????????.OrderBy(?titleField?,?false?)
?????????????????????????.GetDataTable();
????????????int?count3?=?result3.Rows.Count;
下載dll: https://www.codeplex.com/camlquery
最新版本的接口可能有變化,使用時請參考最新的文檔。
附:
原來還有第五種方案: 用 .net3.5的朋友可以試試LINQtoSharePoint,跟o這個.net2.0的好像差不多:
http://www.codeplex.com/LINQtoSharePoint
轉載于:https://www.cnblogs.com/NetUser/archive/2013/03/11/2954191.html
總結
以上是生活随笔為你收集整理的【转】WSS3.0开发--你还在为写CAML痛苦吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux系统:Centos7搭建Red
- 下一篇: 我的管理三板斧理念