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  typeName  =   " My Content Type " ;
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类库,查询语句如下:
SPWeb web  =  SPContext.Current.Web;
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),实现了如下的数据查询语法:
QueryExpression expr  =
             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  System.Data;
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

你可能感兴趣的:(开发)