Hmm... Let me state in advance that this article does not have much practical significance, so students who want to know how to use something can press Alt + F4 (or Ctrl + W). Students who want to know how SharePoint works can continue to scroll down.
I am currently writing a book on SharePoint 2010 development with KB, and I accidentally discovered this method while studying the newly added object model in 2010. We all know that in 2003/2007, SPList's GetItemById method was used to obtain list items based on ID (What, haven't you heard of this method? Then I'm afraid you are not a qualified SharePoint developer...). The name of this newly added method is GetItemByIdSelectedFields (a GetItemByIdAllFields method is also added to accompany it, but this is completely equivalent to GetItemById, so no more nonsense). The definition of the method is as follows:
1: public SPListItem GetItemByIdSelectedFields(int id, params string[] fields)
When I first saw this, I immediately thought of the ViewFields property of SPQuery. When getting a list entry, only certain specified fields are returned to improve efficiency. But when I wrote a Console program to test, I found that it was not what I imagined. For example, I wrote (this method requires writing the internal name):
1: SPListItem item = spList.GetItemByIdSelectedFields(1, "Title", "Created"); 2: Console.WriteLine(item["Modified"]);
This program actually did not report an error, and the Modified value was returned normally, so I tried it. There were actually 50 fields in a custom list whose values were returned normally, but all the query items, users and user groups were returned normally. (In fact, this is essentially a lookup item) None were returned.
Driven by curiosity (it can't kill me yet), I Reflector looked at the source code of this method:
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());
Regarding the last GetItemById, there is no need to delve into it for now. Just know that it is an overload of GetItemById, and its purpose is to find items. The last parameter puts the fields that need to be obtained in the form of CAML. .
The foreach on line 7 is easy to understand. We add the fields we need; but the foreach on line 15 is a bit confusing at the beginning. Do we need to add other fields as well? And what is the MustFetchByDefault of SPField? Let’s dig a little deeper and take a look:
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: }
How to determine whether a field needs to be retrieved? By judging a List attribute of the field, the GetFieldAttributeValue method is no longer posted (otherwise it is suspected of cheating on the word count). In short, it is to find a List from the Xml node similar to the SchemaXml attribute (field description) of the Field. properties. If it is found and it is not GlobalList.Docs (some special thing), then this field is not necessary. In other words, I do not need to return this field to the user.
So what fields have List attributes in SchemaXml? A field with a list of attributes? Check out the item! Ha, it really avoided all the search items. (Docs is the List attribute of the "path" field, which may have some special origin)
Now we know why all other fields are included and the lookup is not included. But why? If we know something about the SharePoint content database, we will know that the query item actually only stores an ID value in the AllUserData table in the content database (but when it is taken out using the object model, it includes the corresponding field of the query item. content), which means that if you want to return the value of the query item, you need to do some additional database operations (such as finding the item being consulted, returning the value of the corresponding field, and assembling it into "1 ;#Administrator" this kind of ghost look). More importantly, if the lookup item is multi-valued, then the lookup item itself is stored in another table (AllUserDataJunctions), so it takes a lot of effort to return it. So there is a new thing added in 2010. If our list contains many lookup items, and we may only use one or two of them (or none at all) for the time being, it seems that using this method can indeed improve a lot. efficiency.