حسنًا... اسمحوا لي أن أذكر مقدمًا أن هذه المقالة ليس لها أهمية عملية كبيرة، لذلك يمكن للطلاب الذين يرغبون في معرفة كيفية استخدام شيء ما الضغط على Alt + F4 (أو Ctrl + W). يمكن للطلاب الذين يريدون معرفة كيفية عمل SharePoint الاستمرار في التمرير لأسفل.
أقوم حاليًا بتأليف كتاب عن تطوير SharePoint 2010 باستخدام قاعدة المعارف، واكتشفت هذه الطريقة بالصدفة أثناء دراسة نموذج الكائن المُضاف حديثًا في عام 2010. نعلم جميعًا أنه في 2003/2007، تم استخدام طريقة GetItemById الخاصة بـ SPList للحصول على عناصر القائمة بناءً على المعرف (ماذا، ألم تسمع عن هذه الطريقة؟ إذن أخشى أنك لست مطور SharePoint مؤهلاً...). اسم هذه الطريقة المضافة حديثًا هو GetItemByIdSelectedFields (تتم أيضًا إضافة طريقة GetItemByIdAllFields لمرافقتها، ولكن هذا يعادل تمامًا GetItemById، لذلك لا مزيد من الهراء. تعريف الطريقة كما يلي:
1: SPListItem GetItemByIdSelectedFields العام (معرف int، حقول سلسلة المعلمات [])
عندما رأيت هذا لأول مرة، فكرت على الفور في خاصية ViewFields الخاصة بـ SPQuery. عند الحصول على إدخال قائمة، يتم إرجاع حقول محددة فقط لتحسين الكفاءة. ولكن عندما كتبت برنامج وحدة التحكم للاختبار، وجدت أنه ليس كما تخيلت، فمثلا كتبت (هذه الطريقة تتطلب كتابة الاسم الداخلي):
1: عنصر SPListItem = spList.GetItemByIdSelectedFields(1, "Title", "Created"); 2: Console.WriteLine(item["Modified"]);
في الواقع، لم يبلغ هذا البرنامج عن خطأ، وتم إرجاع القيمة المعدلة بشكل طبيعي، لذا قمت بتجربتها. كان هناك بالفعل 50 حقلاً في قائمة مخصصة تم إرجاع قيمها بشكل طبيعي، ولكن تم إرجاع جميع عناصر الاستعلام والمستخدمين ومجموعات المستخدمين. تم إرجاعها بشكل طبيعي (في الواقع، هذا عنصر بحث بشكل أساسي) ولم يتم إرجاع أي شيء.
بدافع من الفضول (لا يمكن أن يقتلني بعد)، نظرت I Reflector إلى الكود المصدري لهذه الطريقة:
1: if(field == null) 2: { 3: throw new ArgumentNullException("fields"); 4: } 5: 6: StringBuilder builder = new StringBuilder(); 7: foreach (سلسلة في الحقول) 8: { 9: if (str != null) 10: { 11: builder.Append("<FieldRef Name="" + str + ""/>"); 12: } 13: } 14: 15: foreach (SPField الحقل في this.Fields) 16: { 17: علامة منطقية = خطأ؛ 18: foreach (سلسلة str2 في الحقول) 19: { 20: if (str2 == field.InternalName) 21: { 22: flag = true 23: استراحة 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 .
من السهل فهم foreach في السطر 7، فنحن نضيف الحقول التي نحتاجها؛ لكن foreach في السطر 15 مربكًا بعض الشيء في البداية. وما هو MustFetchByDefault لـ SPField؟ دعونا نتعمق قليلاً ونلقي نظرة:
1: منطقي داخلي MustFetchByDefault 2: { 3: get 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، فسنعرف أن عنصر الاستعلام في الواقع يخزن فقط قيمة معرف في جدول AllUserData في قاعدة بيانات المحتوى (ولكن عندما يتم إخراجها باستخدام نموذج الكائن، فإنه يتضمن الحقل المقابل من محتوى عنصر الاستعلام)، مما يعني أنه إذا كنت تريد إرجاع قيمة عنصر الاستعلام، فستحتاج إلى القيام ببعض عمليات قاعدة البيانات الإضافية (مثل العثور على العنصر الذي تتم استشارته، وإرجاع قيمة الحقل المقابل، وتجميعه في "1؛#المسؤول" هذا النوع من النظرة الشبحية). والأهم من ذلك، إذا كان عنصر البحث متعدد القيم، فسيتم تخزين عنصر البحث نفسه في جدول آخر (AllUserDataJunctions)، لذلك يستغرق الأمر الكثير من الجهد لإعادته. لذا فقد تمت إضافة شيء جديد في عام 2010. إذا كانت قائمتنا تحتوي على العديد من عناصر البحث، وقد نستخدم واحدًا أو اثنين منها فقط (أو لا نستخدمها على الإطلاق) في الوقت الحالي، فيبدو أن استخدام هذه الطريقة يمكن أن يؤدي بالفعل إلى تحسين الكثير . كفاءة.