WEB开发网
开发学院WEB开发ASP SharePoint 2010中新增的GetItemByIdSelectedFiel... 阅读

SharePoint 2010中新增的GetItemByIdSelectedFields方法

 2010-02-05 10:46:09 来源:WEB开发网   
核心提示:唔……事先声明,其实这篇文章没有太多实际的使用意义,SharePoint 2010中新增的GetItemByIdSelectedFields方法,所以想了解某个东东怎么用的同学可以按Alt + F4(或者Ctrl + W)了,想了解SharePoint里面是怎么工作的同学可以继续往下翻,如果我们的列表中包含好多个查阅项
唔……事先声明,其实这篇文章没有太多实际的使用意义,所以想了解某个东东怎么用的同学可以按Alt + F4(或者Ctrl + W)了。想了解SharePoint里面是怎么工作的同学可以继续往下翻。

最近正在和KB一起写关于SharePoint 2010开发方面的一本书,在研究2010新增加的对象模型的时候,偶然发现了这个方法。我们都知道在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了一下这个方法的源代码:

  1: if(field == null)  2: {  3:  throw new ArgumentNullException("fields");  4: }  5:   6: StringBuilder builder = new StringBuilder();  7: foreach (string str in fields)  8: {  9:  if (str != null) 10:  { 11:   builder.Append("<FieldRef Name=\"" + str + "\"/>"); 12:  } 13: } 14:  15: foreach (SPField field in this.Fields) 16: { 17:  bool flag = false; 18:  foreach (string str2 in fields) 19:  { 20:   if (str2 == field.InternalName) 21:   { 22:    flag = true; 23:    break; 24:   } 25:  } 26:  if (!flag && field.MustFetchByDefault) 27:  { 28:   builder.Append("<FieldRef Name=\""); 29:   builder.Append(field.InternalName); 30:   builder.Append("\"/>"); 31:  } 32: } 33:  34: return this.GetItemById(id, null, false, builder.ToString());
关于最后那个GetItemById是怎么回事,暂时先不用再去深究了,只要知道它是一个GetItemById的重载,目的就是查找条目用的就行了,最后一个参数把需要获取的字段以CAML的形式放进去。

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

  1: internal bool MustFetchByDefault  2: {  3:  get  4:  {  5:   string fieldAttributeValue = this.GetFieldAttributeValue("List");  6:   if(!string.IsNullOrEmpty(fieldAttributeValue) &&  7:    (fieldAttrbuteValue != GlobalList.Docs.ToString()))  8:   {  9:    return false; 10:   } 11:   return true; 12:  } 13: }


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

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

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

Tags:SharePoint 新增 GetItemByIdSelectedFields

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接