SharePoint 2010中新增的GetItemByIdSelectedFields方法

 我们都知道在2003/2007里面,根据ID获取列表条目使用的是SPList的GetItemById方法(什么,没听说过这个方法?那恐怕你不是一个合格的SharePoint开发人员……)。新增加的这个方法名字叫GetItemByIdSelectedFields(同时也增加了一个GetItemByIdAllFields的方法与之作伴,不过这个和GetItemById是完全等效的,就不再废话了),方法的定义是这样的:

   1: public SPListItem GetItemByIdSelectedFields(int id, params string[] fields)
当我第一眼看到这个的时候,立刻就想到了SPQuery的那个ViewFields属性,获取某个列表条目的时候,只返回某些指定的字段,来提高效率。可是当我写了个Console程序试验的时候,发现并不是我想象中的样子,比如我写成(这个方法要求写内部名称):

   1: SPListItem item = spList.GetItemByIdSelectedFields(1, "Title", "Created");   2: Console.WriteLine(item["Modified"]);

这段程序居然没有报错,而且Modified的值也正常返回了,于是我试了试,一个自定义列表里面居然有50来个字段的值都正常返回了,但是所有的查阅项、用户和用户组(其实这个本质上也是查阅项)都没有返回。

在好奇驱使下(暂时还害不死我),我Reflector了一下这个方法的源代码:

if(field == null)
 {  
 throw new ArgumentNullException("fields");  
 }  
 StringBuilder builder = new StringBuilder();  
 foreach (string str in fields)   
{   
 if (str != null)  
  {  
  builder.Append("<FieldRef Name=\"" + str + "\"/>"); 
  }  
}  

 foreach (SPField field in this.Fields) 
 {  
  bool flag = false;  
  foreach (string str2 in fields) 
  { 
    if (str2 == field.InternalName)  
   { 
    flag = true;  
      break; 
   } 
 } 
  if (!flag && field.MustFetchByDefault)  
 {  
    builder.Append("<FieldRef Name=\"");  
    builder.Append(field.InternalName);  
    builder.Append("\"/>");  
   }  
}  
 return this.GetItemById(id, null, false, builder.ToString());

关于最后那个GetItemById是怎么回事,暂时先不用再去深究了,只要知道它是一个GetItemById的重载,目的就是查找条目用的就行了,最后一个参数把需要获取的字段以CAML的形式放进去。

第7行那个foreach很好理解,把我们需要的字段加进去;但是第15行的那个foreach一开始就有点让人摸不着头脑了,还要把其他字段也放进去?而且SPField的这个MustFetchByDefault是什么东西?再挖挖看看:

internal bool MustFetchByDefault { 
get   
 {  
  string fieldAttributeValue = this.GetFieldAttributeValue("List");
    if(!string.IsNullOrEmpty(fieldAttributeValue) &&  (fieldAttrbuteValue != GlobalList.Docs.ToString()))  
    {  
    return false;  
    }  
   return true; 
 } 
}



如何判断一个字段是不是要取呢?通过判断字段的一个List属性,至于GetFieldAttributeValue方法就不再往上贴了(否则有骗字数的嫌疑),总之它是从Field的类似SchemaXml属性(字段描述)的Xml结点中,去找一个List的属性。如果找到了,而且不是GlobalList.Docs(某个特殊的东东)的话,那么这个字段就不是必须的,换句话说这个字段我就不用返回给用户。

那什么字段的SchemaXml里会有List属性?一个字段里有一个和列表的属性?查阅项!哈,真的是回避掉了所有的查阅项。(Docs这个东西是“路径”这个字段的List属性,估计有某些特殊的来源)

现在我们知道为什么会包含其他所有字段,并且不包含查阅项了。但是为什么要这样?如果我们对SharePoint的内容数据库有所了解的话,我们会知道其实查阅项在内容数据库里只存了一个ID值在AllUserData表里面(但是用对象模型取出来的时候,是包含查阅那个条目相应字段的内容的),这也就意味着,如果要返回查阅项的值,就需要多做一些额外的数据库操作(比如再去找到被查阅的那个条目,把相应字段的值返回来,拼装成“1;#Administrator“这种鬼样子)。更重要的是,如果这个查阅项是一个多值的,那么这个查阅项本身都是保存在另外一个表中的(AllUserDataJunctions),这样要返回起来还真是要费不少功夫。所以2010里面新增加了这么一个东西,如果我们的列表中包含好多个查阅项,而我们可能暂时只用到其中一两个(或者一个都不用)的话,看来用这个方法确实能提高不少效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值