Hmm... Permítanme decirles de antemano que este artículo no tiene mucha importancia práctica, por lo que los estudiantes que quieran saber cómo usar algo pueden presionar Alt + F4 (o Ctrl + W). Los estudiantes que quieran saber cómo funciona SharePoint pueden continuar desplazándose hacia abajo.
Actualmente estoy escribiendo un libro sobre el desarrollo de SharePoint 2010 con KB y accidentalmente descubrí este método mientras estudiaba el modelo de objetos recién agregado en 2010. Todos sabemos que en 2003/2007, el método GetItemById de SPList se usaba para obtener elementos de la lista según el ID (¿Qué? ¿No has oído hablar de este método? Entonces me temo que no eres un desarrollador calificado de SharePoint...). El nombre de este método recién agregado es GetItemByIdSelectedFields (también se agrega un método GetItemByIdAllFields para acompañarlo, pero esto es completamente equivalente a GetItemById, por lo que no más tonterías. La definición del método es la siguiente:
1: SPListItem público GetItemByIdSelectedFields (int id, campos de cadena de parámetros [])
Cuando vi esto por primera vez, inmediatamente pensé en la propiedad ViewFields de SPQuery. Al obtener una entrada de lista, solo se devuelven ciertos campos específicos para mejorar la eficiencia. Pero cuando escribí un programa de consola para probar, descubrí que no era lo que imaginaba. Por ejemplo, escribí (este método requiere escribir el nombre interno):
1: elemento SPListItem = spList.GetItemByIdSelectedFields(1, "Título", "Creado"); 2: Console.WriteLine(elemento["Modificado"]);
En realidad, este programa no informó ningún error y el valor Modificado se devolvió normalmente, así que lo probé. En realidad, había 50 campos en una lista personalizada cuyos valores se devolvieron normalmente, pero todos los elementos de consulta, usuarios y grupos de usuarios sí. devuelto normalmente. (De hecho, esto es esencialmente un elemento de búsqueda) No se devolvió ninguno.
Impulsado por la curiosidad (todavía no puede matarme), Reflector miré el código fuente de este método:
1: if(field == null) 2: { 3: throw new ArgumentNullException("fields"); 4: } 5: 6: StringBuilder builder = new StringBuilder(); foreach (cadena en campos) 8: { 9: if (str! = null) 10: { 11: builder.Append("<FieldRef Name="" + str + ""/>"); 12: } 13: } 14: 15: foreach (SPField) campo en this.Fields) 16: { 17: bool flag = false; 18: foreach (cadena str2 en campos) 19: { 20: if (str2 == campo.InternalName) 21: { 22: flag = true; 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: devuelve this.GetItemById(id, null, false, builder.ToString());
Con respecto al último GetItemById, no es necesario profundizar en él por ahora. Solo sepa que es una sobrecarga de GetItemById y su propósito es encontrar elementos. El último parámetro coloca los campos que deben obtenerse en forma de CAML. .
El foreach de la línea 7 es fácil de entender. Agregamos los campos que necesitamos, pero el foreach de la línea 15 es un poco confuso al principio. ¿Y cuál es el MustFetchByDefault de SPField? Profundicemos un poco más y echemos un vistazo:
1: bool interno MustFetchByDefault 2: { 3: obtener 4: { 5: cadena fieldAttributeValue = this.GetFieldAttributeValue("List"); 6: if(!string.IsNullOrEmpty(fieldAttributeValue) && 7: (fieldAttrbuteValue! = GlobalList.Docs. ToString())) 8: { 9: devuelve falso; 10: } 11: devuelve verdadero 12: } 13: }
¿Cómo determinar si es necesario recuperar un campo? Al juzgar un atributo de Lista del campo, el método GetFieldAttributeValue ya no se publica (de lo contrario, se sospecha que hace trampa en el recuento de palabras). En resumen, es encontrar una Lista del nodo Xml similar al atributo SchemaXml (descripción del campo). ) de las propiedades del campo. Si se encuentra y no es GlobalList.Docs (algo especial), entonces este campo no es necesario. En otras palabras, no necesito devolver este campo al usuario.
Entonces, ¿qué campos tienen atributos de Lista en SchemaXml? ¿Un campo con una lista de atributos? ¡Mira el artículo! Ja, realmente evitó todos los elementos de búsqueda. (Docs es el atributo Lista del campo "ruta", que puede tener algún origen especial)
Ahora sabemos por qué se incluyen todos los demás campos y la búsqueda no. ¿Pero por qué? Si sabemos algo sobre la base de datos de contenido de SharePoint, sabremos que el elemento de consulta en realidad solo almacena un valor de ID en la tabla AllUserData en la base de datos de contenido (pero cuando se extrae usando el modelo de objetos, incluye el campo correspondiente de la base de datos de contenido). elemento de consulta. contenido), lo que significa que si desea devolver el valor del elemento de consulta, debe realizar algunas operaciones adicionales en la base de datos (como encontrar el elemento que se está consultando, devolver el valor del campo correspondiente y ensamblarlo en "1 ;#Administrator" este tipo de mirada fantasma). Más importante aún, si el elemento de búsqueda tiene varios valores, entonces el elemento de búsqueda en sí se almacena en otra tabla (AllUserDataJunctions), por lo que se necesita mucho esfuerzo para devolverlo. Entonces, se agregó algo nuevo en 2010. Si nuestra lista contiene muchos elementos de búsqueda y solo podemos usar uno o dos de ellos (o ninguno) por el momento, parece que usar este método puede mejorar mucho. . eficiencia.