อืม... ขอแจ้งล่วงหน้าว่าบทความนี้ไม่ได้มีความสำคัญเชิงปฏิบัติมากนัก ดังนั้นนักเรียนที่ต้องการทราบวิธีใช้บางอย่างสามารถกด Alt + F4 (หรือ Ctrl + W) นักเรียนที่ต้องการทราบวิธีการทำงานของ SharePoint สามารถเลื่อนลงไปด้านล่างได้
ขณะนี้ฉันกำลังเขียนหนังสือเกี่ยวกับการพัฒนา SharePoint 2010 ด้วย KB และฉันบังเอิญค้นพบวิธีนี้ในขณะที่ศึกษาโมเดลออบเจ็กต์ที่เพิ่มเข้ามาใหม่ในปี 2010 เราทุกคนทราบดีว่าในปี 2546/2550 วิธี GetItemById ของ SPList ถูกนำมาใช้เพื่อรับรายการข้อมูลตาม ID (อะไรนะ คุณไม่เคยได้ยินเกี่ยวกับวิธีนี้มาก่อน ฉันกลัวว่าคุณไม่ใช่นักพัฒนา SharePoint ที่มีคุณสมบัติเหมาะสม...) ชื่อของวิธีที่เพิ่มเข้ามาใหม่นี้คือ GetItemByIdSelectedFields (ยังมีการเพิ่มเมธอด GetItemByIdAllFields เข้าไปด้วย แต่จะเทียบเท่ากับ GetItemById โดยสิ้นเชิง ดังนั้นจึงไม่มีเรื่องไร้สาระอีกต่อไป)
1: SPListItem GetItemByIdSelectedFields สาธารณะ (int id, ฟิลด์ params string[])
เมื่อฉันเห็นสิ่งนี้ครั้งแรก ฉันนึกถึงคุณสมบัติ ViewFields ของ SPQuery ทันที เมื่อได้รับรายการ ระบบจะส่งคืนเฉพาะบางฟิลด์ที่ระบุเพื่อปรับปรุงประสิทธิภาพ แต่เมื่อฉันเขียนโปรแกรม Console เพื่อทดสอบ ฉันพบว่ามันไม่ใช่สิ่งที่ฉันจินตนาการไว้ เช่น ฉันเขียน (วิธีนี้ต้องเขียนชื่อภายใน):
1: รายการ SPListItem = spList.GetItemByIdSelectedFields (1, "ชื่อ", "สร้างแล้ว"); 2: Console.WriteLine (รายการ ["แก้ไข"]);
โปรแกรมนี้ไม่ได้รายงานข้อผิดพลาดจริง ๆ และค่าที่แก้ไขก็ถูกส่งกลับตามปกติ ดังนั้นฉันจึงลองใช้จริง ๆ แล้วมี 50 ฟิลด์ในรายการที่กำหนดเองซึ่งค่าจะถูกส่งกลับตามปกติ แต่รายการค้นหา ผู้ใช้ และกลุ่มผู้ใช้ทั้งหมดกลับเป็น ส่งคืนตามปกติ (อันที่จริงนี่เป็นรายการค้นหา) ไม่มีการส่งคืน
ด้วยความอยากรู้อยากเห็น (มันยังฆ่าฉันไม่ได้) ฉัน Reflector ดูซอร์สโค้ดของวิธีนี้:
1: if(field == null) 2: { 3: โยน new ArgumentNullException("fields"); 4: } 5: 6: StringBuilder builder = new StringBuilder(); 7: foreach (สตริง str ในฟิลด์) 8: { 9: if (str != null) 10: { 11: builder.Append("<FieldRef Name="" + str + ""/>"); 12: } 13: } 14: 15: foreach (SPField สนามใน this.Fields) 16: { 17: bool flag = false; 18: foreach (สตริง str2 ในฟิลด์) 19: { 20: if (str2 == field.InternalName) 21: { 22: flag = true; แบ่ง; 24: } 25: } 26: ถ้า (!flag && field.MustFetchByDefault) 27: { 28: builder.Append("<FieldRef Name=""); 29: builder.Append(field.InternalName); 30 : builder.Append(""/>"); 31: } 32: } 33: 34: ส่งคืน this.GetItemById(id, null, false, builder.ToString());
สำหรับ GetItemById ครั้งล่าสุด ไม่จำเป็นต้องเจาะลึกลงไปอีก แค่รู้ว่า GetItemById มีภาระมากเกินไป และจุดประสงค์คือเพื่อค้นหารายการต่างๆ .
foreach ในบรรทัดที่ 7 นั้นง่ายต่อการเข้าใจ เราเพิ่มฟิลด์ที่เราต้องการ แต่ foreach ในบรรทัด 15 นั้นค่อนข้างสับสนในตอนเริ่มต้น เราจำเป็นต้องเพิ่มฟิลด์อื่นด้วยหรือไม่ และ MustFetchByDefault ของ SPField คืออะไร มาเจาะลึกลงไปอีกหน่อยแล้วลองดู:
1: บูลภายใน MustFetchByDefault 2: { 3: รับ 4: { 5: string fieldAttributeValue = this.GetFieldAttributeValue("List"); 6: if(!string.IsNullOrEmpty(fieldAttributeValue) && 7: (fieldAttrbuteValue != GlobalList.Docs. ToString())) 8: { 9: กลับเท็จ; 10: } 11: กลับจริง; 12: } 13: }
จะทราบได้อย่างไรว่าจำเป็นต้องดึงข้อมูลฟิลด์หรือไม่? โดยการตัดสินแอตทริบิวต์รายการของฟิลด์ วิธีการ GetFieldAttributeValue จะไม่ถูกโพสต์อีกต่อไป (ไม่เช่นนั้นจะสงสัยว่ามีการโกงจำนวนคำ) กล่าวโดยย่อคือการค้นหารายการจากโหนด Xml ที่คล้ายกับแอตทริบิวต์ SchemaXml (คำอธิบายฟิลด์ ) ของคุณสมบัติของสนาม หากพบและไม่ใช่ GlobalList.Docs (บางสิ่งพิเศษ) แสดงว่าฟิลด์นี้ไม่จำเป็น กล่าวคือ ฉันไม่จำเป็นต้องส่งคืนฟิลด์นี้ให้กับผู้ใช้
แล้วฟิลด์ใดที่มีแอตทริบิวต์รายการใน SchemaXml ฟิลด์ที่มีรายการแอตทริบิวต์? ตรวจสอบรายการ! ฮา มันหลีกเลี่ยงรายการค้นหาทั้งหมดจริงๆ (เอกสารคือแอตทริบิวต์รายการของช่อง "เส้นทาง" ซึ่งอาจมีต้นกำเนิดพิเศษบางอย่าง)
ตอนนี้เรารู้แล้วว่าเหตุใดจึงรวมฟิลด์อื่นๆ ทั้งหมดไว้และไม่รวมการค้นหา แต่ทำไม? ถ้าเรารู้บางอย่างเกี่ยวกับฐานข้อมูลเนื้อหา SharePoint เราจะรู้ว่ารายการแบบสอบถามจริง ๆ แล้วเก็บเฉพาะค่า ID ในตาราง AllUserData ในฐานข้อมูลเนื้อหา (แต่เมื่อนำออกมาโดยใช้โมเดลวัตถุ รายการนั้นจะรวมฟิลด์ที่เกี่ยวข้องของ รายการสืบค้นเนื้อหา) ซึ่งหมายความว่าหากคุณต้องการส่งคืนค่าของรายการสืบค้น คุณจะต้องดำเนินการฐานข้อมูลเพิ่มเติมบางอย่าง (เช่น ค้นหารายการที่กำลังปรึกษา ส่งกลับค่าของฟิลด์ที่เกี่ยวข้อง และประกอบเข้าด้วยกัน “1 ;#Administrator” หน้าตาผีแบบนี้) ที่สำคัญกว่านั้น ถ้ารายการค้นหามีหลายค่า รายการค้นหานั้นจะถูกจัดเก็บไว้ในตารางอื่น (AllUserDataJunctions) ดังนั้นจึงต้องใช้ความพยายามอย่างมากในการส่งคืน จึงมีสิ่งใหม่ๆ เพิ่มเข้ามาในปี 2010 หากรายการของเรามีรายการค้นหาจำนวนมาก และเราอาจใช้เพียงหนึ่งหรือสองรายการเท่านั้น (หรือไม่มีเลย) ในขณะนี้ ดูเหมือนว่าการใช้วิธีนี้สามารถปรับปรุงได้มากจริงๆ . ประสิทธิภาพ.