进行WSS3或MOSS开发的朋友不可避免的要处理各种List的查询,编写类似下面的CAML语句:
 <Where>
<Where> <And>
<And> <And>
 <And> <Eq><FieldRef Name=”Title”><Value Type=”Text”>Value</Value></Eq>
  <Eq><FieldRef Name=”Title”><Value Type=”Text”>Value</Value></Eq> <Eq><FieldRef Name=”ContentType”><Value Type=”Text”>Product</Value></Eq>
  <Eq><FieldRef Name=”ContentType”><Value Type=”Text”>Product</Value></Eq> </And>
 </And> <Eq><FieldRef Name=”Field1”><Value Type=”Text”>Value</Value></Eq>
 <Eq><FieldRef Name=”Field1”><Value Type=”Text”>Value</Value></Eq> </And>
</And>  <Or>
<Or> <Or>
 <Or> <Eq><FieldRef Name=”Title”><Value Type=”Text”>Value</Value></Eq>
  <Eq><FieldRef Name=”Title”><Value Type=”Text”>Value</Value></Eq> <Eq><FieldRef Name=”ContentType”><Value Type=”Text”>Product</Value></Eq>
  <Eq><FieldRef Name=”ContentType”><Value Type=”Text”>Product</Value></Eq> </Or>
 </Or> <Eq><FieldRef Name=”Field1”><Value Type=”Text”>Value</Value></Eq>
 <Eq><FieldRef Name=”Field1”><Value Type=”Text”>Value</Value></Eq> </Or>
</Or>  </Where>
</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 typeName = "My Content Type";
string typeName = "My Content Type"; string simpleQuery =
string simpleQuery = CAML.Query(
    CAML.Query( CAML.Where(
        CAML.Where( CAML.Or(
            CAML.Or( CAML.Eq(
                CAML.Eq( CAML.FieldRef("ContentType"),
                    CAML.FieldRef("ContentType"),  CAML.Value(typeName)),
                    CAML.Value(typeName)), CAML.IsNotNull(
                CAML.IsNotNull( CAML.FieldRef("Description")))),
                    CAML.FieldRef("Description")))), CAML.GroupBy(
        CAML.GroupBy( true,
            true, CAML.FieldRef("Title",CAML.SortType.Descending)),
            CAML.FieldRef("Title",CAML.SortType.Descending)), CAML.OrderBy(
        CAML.OrderBy( CAML.FieldRef("_Author"),
            CAML.FieldRef("_Author"), CAML.FieldRef("AuthoringDate"),
            CAML.FieldRef("AuthoringDate"), CAML.FieldRef("AssignedTo",CAML.SortType.Ascending))
            CAML.FieldRef("AssignedTo",CAML.SortType.Ascending)) );
    );
3)还有一位兄弟写了个支持用sql语句形式的caml类库,查询语句如下:
 SPWeb web = SPContext.Current.Web;
SPWeb web = SPContext.Current.Web; string queryStr = "SELECT * FROM 通知 WHERE ID>10";
string queryStr = "SELECT * FROM 通知 WHERE ID>10"; FriendlyQuery query = new FriendlyQuery(web, queryStr);
FriendlyQuery query = new FriendlyQuery(web, queryStr); query.RowLimit = 100;
query.RowLimit = 100; query.Scope = FriendlyQuery.QueryScope. AllItemsAndFolders;
query.Scope = FriendlyQuery.QueryScope. AllItemsAndFolders; SPListItemCollection items = query.GetItems();
SPListItemCollection items = query.GetItems(); foreach(SPListItem i in items)
foreach(SPListItem i in items) Response.Write(i.Title + "<br/>");
    Response.Write(i.Title + "<br/>");上面的三种方案,个人还是比较喜欢CAML.net的实现,纯代码,但是它的语法不是那么的"优雅"。
以前写过一个数据库ORM工具,见(DBO),实现了如下的数据查询语法:
 QueryExpression expr =
QueryExpression expr =
 DboQuery.Select( User.__UserName,Org.__OrgName )
             DboQuery.Select( User.__UserName,Org.__OrgName )
 .From<User>()
             .From<User>()
 .InnerJoin<Org>().On(User.__OrgId, Org.__OrgId)
             .InnerJoin<Org>().On(User.__OrgId, Org.__OrgId)
 .Where(Org.__OrgId == 2 | Org.__OrgId == 3);
             .Where(Org.__OrgId == 2 | Org.__OrgId == 3);
 IList<RefOrgUser> orgs = _session.Query<RefOrgUser>(expr) ;
 IList<RefOrgUser> orgs = _session.Query<RefOrgUser>(expr) ;于是,计划开发类似语法的CAML查询类库--CodeArt.SharePoint.CAMLQuery.dll。
07年六月份开始开发,已经用到了实际的项目中,实现了几个复杂的查询功能,好东西不敢独享,哈哈,给大家show一下。
(在后面大家可以找到dll的下载链接)
以下的代码示例针对一个列表CAMLList做查询,此列表有如下字段:标题,正文,修改时间。
首先,引用名称空间。
 using System.Data;
using System.Data; using Microsoft.SharePoint;
using Microsoft.SharePoint; using CodeArt.SharePoint.CAMLQuery;
using CodeArt.SharePoint.CAMLQuery;代码1:查询标题中包含"XXX"的 项目:
 QueryField titleField = new QueryField("标题");
  QueryField titleField = new QueryField("标题");
 SPSite site = new SPSite("http://jyserver:9000");
  SPSite site = new SPSite("http://jyserver:9000"); SPList list =  site.RootWeb.Lists["CAMLTest"];
  SPList list =  site.RootWeb.Lists["CAMLTest"];
 SPQuery q = new SPQuery ();
   SPQuery q = new SPQuery ();
 q.Query = CAMLBuilder.Where( list , titleField.Contains("XXX") );
   q.Query = CAMLBuilder.Where( list , titleField.Contains("XXX") ); 
            SPListItemCollection items = list.GetItems(q);
   SPListItemCollection items = list.GetItems(q);
 int count = items.Count;
   int count = items.Count;          代码2:查询标题中包含"XXX"或"YYY"的 项目:
 SPList list = this.GetTestList();
 SPList list = this.GetTestList();
 ICAMLExpression expr = QueryModel.Title.Contains("XXX") || QueryModel.Title.Contains("YYY");
  ICAMLExpression expr = QueryModel.Title.Contains("XXX") || QueryModel.Title.Contains("YYY");            
 PQuery q = new SPQuery();
  PQuery q = new SPQuery();
 q.Query = CAMLBuilder.Where(list, expr );
  q.Query = CAMLBuilder.Where(list, expr );
 SPListItemCollection items = list.GetItems(q);
  SPListItemCollection items = list.GetItems(q);
 int count = items.Count;
  int count = items.Count;代码3:我们可以创建一个查询模型,类似一个实体类,针对这个类进行查询:
 /// <summary>
/// <summary> /// 查询模型
        /// 查询模型 /// </summary>
        /// </summary> class QueryModel
        class QueryModel {
        { public static FieldRef<QueryModel> Title = new FieldRef<QueryModel>("标题");
            public static FieldRef<QueryModel> Title = new FieldRef<QueryModel>("标题"); public static FieldRef<QueryModel> Body = new FieldRef<QueryModel>("正文");
            public static FieldRef<QueryModel> Body = new FieldRef<QueryModel>("正文"); public static TypeFieldRef<QueryModel, DateTime> ModifyTime = new TypeFieldRef<QueryModel, DateTime>("修改时间");
            public static TypeFieldRef<QueryModel, DateTime> ModifyTime = new TypeFieldRef<QueryModel, DateTime>("修改时间"); }
        }
 [TestMethod]
        [TestMethod] public void TestModelQuery()
        public void TestModelQuery() {
        {           SPList list = this.GetTestList();
            SPList list = this.GetTestList();
 SPQuery q = new SPQuery();
            SPQuery q = new SPQuery();
 q.Query = CAMLBuilder.Where( list ,  QueryModel.Title.Contains("XXX") );
            q.Query = CAMLBuilder.Where( list ,  QueryModel.Title.Contains("XXX") ); q.ViewFields = CAMLBuilder.ViewFields( list , QueryModel.Title, QueryModel.Body);
            q.ViewFields = CAMLBuilder.ViewFields( list , QueryModel.Title, QueryModel.Body);
 SPListItemCollection items = list.GetItems(q);
            SPListItemCollection items = list.GetItems(q);
 int count = items.Count;
            int count = items.Count; }
        }代码4:按照逻辑动态拼接查询,以下示例查询标题中包含"XXX"或"YYY"的 项目,按照queryByTime 参数,附加修改时间条件:
 SPList list = this.GetTestList();
 SPList list = this.GetTestList();
 bool queryByTime = true ;
  bool queryByTime = true ;
 TypedCAMLExpression<QueryModel> expr = QueryModel.Title.Contains("XXX") || QueryModel.Title.Contains("YYY");
  TypedCAMLExpression<QueryModel> expr = QueryModel.Title.Contains("XXX") || QueryModel.Title.Contains("YYY");     
         if( queryByTime )
  if( queryByTime ) expr = expr & QueryModel.ModifyTime >= DateTime.Now.AddDays(-1)
        expr = expr & QueryModel.ModifyTime >= DateTime.Now.AddDays(-1)
 SPQuery q = new SPQuery();
   SPQuery q = new SPQuery();
 q.Query = CAMLBuilder.Where(list, expr );
   q.Query = CAMLBuilder.Where(list, expr );
 SPListItemCollection items = list.GetItems(q);
   SPListItemCollection items = list.GetItems(q);
 int count = items.Count;
  int count = items.Count;代码5:我们可以用类似sql的强类型语法:
 QueryField titleField = new QueryField("标题");
 QueryField titleField = new QueryField("标题"); QueryField bodyField = new QueryField("正文");
 QueryField bodyField = new QueryField("正文");
 SPList list = this.GetTestList();
            SPList list = this.GetTestList(); //只查询两个字段
            //只查询两个字段 SPListItemCollection result1 =
            SPListItemCollection result1 = ListQuery.Select(titleField, bodyField)
                ListQuery.Select(titleField, bodyField) .From(list)
                        .From(list) .Where(titleField.Contains("XXX"))
                        .Where(titleField.Contains("XXX")) .GetItems();
                        .GetItems();
 int count = result1.Count;
            int count = result1.Count; //查询所有字段
            //查询所有字段 SPListItemCollection result2 =
            SPListItemCollection result2 = ListQuery.From(list)
                ListQuery.From(list) .Where(titleField.Contains("XXX"))
                         .Where(titleField.Contains("XXX")) .GetItems();
                         .GetItems();
 int count2 = result2.Count;
            int count2 = result2.Count;
 //直接返回DataTable
            //直接返回DataTable DataTable result3 =
            DataTable result3 = ListQuery.Select(titleField,bodyField)
                ListQuery.Select(titleField,bodyField) .From(list)
                        .From(list) .Where(titleField.Contains("XXX")|titleField.Contains("YYY"))
                         .Where(titleField.Contains("XXX")|titleField.Contains("YYY")) .OrderBy( titleField , false )
                         .OrderBy( titleField , false ) .GetDataTable();
                         .GetDataTable();
 int count3 = result3.Rows.Count;
            int count3 = result3.Rows.Count;
下载dll: https://www.codeplex.com/camlquery
最新版本的接口可能有变化,使用时请参考最新的文档。
附:
原来还有第五种方案: 用 .net3.5的朋友可以试试LINQtoSharePoint,跟o这个.net2.0的好像差不多:
http://www.codeplex.com/LINQtoSharePoint
 
                     
                    
                 
                    
                 
 
        

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号