DevExpress eXpressApp Framework (XAF) والكائنات الثابتة eXpress (XPO):كيف يمكنني تسريع وقت تحميل الجمعيات؟
-
09-06-2019 - |
سؤال
أواجه مشكلة في سرعة الوصول إلى خاصية اقتران تحتوي على عدد كبير من السجلات.
لدي تطبيق XAF مع فئة أصل تسمى MyParent
.
هناك 230 سجلا MyParent
.
MyParent
لديه فئة فرعية تسمى MyChild
.
هناك 49000 سجل في MyChild
.
لدي ارتباط محدد بين MyParent
و MyChild
بالطريقة القياسية:
في MyChild
:
// MyChild (many) and MyParent (one)
[Association("MyChild-MyParent")]
public MyParent MyParent;
و في MyParent
:
[Association("MyChild-MyParent", typeof(MyChild))]
public XPCollection<MyCHild> MyCHildren
{
get { return GetCollection<MyCHild>("MyCHildren"); }
}
هناك محددة MyParent
سجل يسمى MyParent1
.
ل MyParent1
, ، هناك 630 MyChild
السجلات.
لدي عرض تفصيلي لفئة تسمى MyUI
.
يختار المستخدم عنصرًا في قائمة منسدلة واحدة في MyUI
DetailView، ويجب أن يملأ الكود الخاص بي قائمة منسدلة أخرى MyChild
أشياء.
يختار المستخدم MyParent1
في القائمة المنسدلة الأولى.
لقد أنشأت عقارًا في MyUI
لإرجاع مجموعة من MyChild
كائنات للقيمة المحددة في القائمة المنسدلة الأولى.
وهذا هو الكود الخاص بالعقار:
[NonPersistent]
public XPCollection<MyChild> DisplayedValues
{
get
{
Session theSession;
MyParent theParentValue;
XPCollection<MyCHild> theChildren;
theParentValue = this.DropDownOne;
// get the parent value
if theValue == null)
{
// if none
return null;
// return null
}
theChildren = theParentValue.MyChildren;
// get the child values for the parent
return theChildren;
// return it
}
لقد وضعت علامة على DisplayedValues
الملكية كما NonPersistent
لأنه مطلوب فقط لواجهة المستخدم الخاصة بـ DetailVIew.لا أعتقد أن الاستمرار في ذلك سيؤدي إلى تسريع إنشاء المجموعة في المرة الأولى، وبعد استخدامها لملء القائمة المنسدلة، لا أحتاج إليها، لذلك لا أريد قضاء الوقت في تخزينها.
المشكلة هي أن الاتصال يستغرق 45 ثانية theParentValue = this.DropDownOne
.
المواصفات:
- فيستا بيزنس
- 8 جيجابايت من ذاكرة الوصول العشوائي
- معالج E6550 بسرعة 2.33 جيجا هرتز
- سكل سيرفر اكسبرس 2005
يعد هذا وقتًا طويلاً جدًا بحيث لا يستطيع المستخدمون انتظار إحدى القوائم المنسدلة العديدة في DetailView.
لقد أخذت الوقت الكافي لتوضيح دراسة الجدوى لأن لدي سؤالين:
كيف يمكنني جعل القيم المرتبطة يتم تحميلها بشكل أسرع؟
هل هناك طريقة أخرى (بسيطة) لبرمجة القوائم المنسدلة وDetailView التي تعمل بشكل أسرع؟
نعم، يمكنك القول أن 630 عدد كبير جدًا من العناصر التي لا يمكن عرضها في القائمة المنسدلة، ولكن هذا الرمز يستغرق وقتًا طويلاً وأظن أن السرعة تتناسب مع 49000 وليس مع 630.100 عنصر في القائمة المنسدلة لن تكون كثيرة جدًا بالنسبة لتطبيقي.
أحتاج إلى عدد لا بأس به من هذه القوائم المنسدلة في تطبيقي، لذلك ليس من المناسب إجبار المستخدم على إدخال معايير تصفية أكثر تعقيدًا لكل منها.يحتاج المستخدم إلى اختيار قيمة واحدة ورؤية القيم ذات الصلة.
سأتفهم إذا كان العثور على عدد كبير من السجلات أمرًا بطيئًا، لكن العثور على بضع مئات من السجلات لن يستغرق وقتًا طويلاً.
المحلول
أولاً، أنت على حق في التشكيك في أن هذه العملية يجب أن تستغرق كل هذا الوقت، ويجب أن تضيف XPO في عمليات القراءة فقط ما بين 30 إلى 70% من الحمل، وعلى هذه الكمية الضئيلة من البيانات يجب أن نتحدث عن ملي ثانية وليس ثوانٍ.
تتوفر بعض نصائح الأداء العامة في منتديات DevExpress، وتتمحور حول التخزين المؤقت للكائنات، والتحميلات البطيئة مقابل التحميلات العميقة، وما إلى ذلك، ولكن أعتقد في حالتك أن المشكلة شيء آخر، ولسوء الحظ من الصعب جدًا تخمين ما يحدث من سؤالك، فقط على سبيل المثال، من غير المرجح أن تكون هناك مشكلة في XPO، فمن المرجح أن تكون مشكلة أخرى، وسأميل إلى إلقاء نظرة على إنشاء الجلسة (وهذا يؤدي أيضًا إلى إنشاء ذاكرة التخزين المؤقت للكائن) ورمز اتصال SQL (عناصر IDataStore)، والاتصالات هي غالبًا ما يكون بطيئًا إذا لم يكن من الممكن حل الأجهزة المضيفة بشكل نظيف، وإذا لم تقم بتجميع/إعادة استخدام الاتصالات، فقد تتفاقم هذه المشكلة.
نصائح أخرى
لست متأكدًا من سبب قيامك بذلك بالطريقة التي أنت بها.إذا قمت بإنشاء ارتباط مثل هذا:
public class A : XPObject
{
[Association("a<b", typeof(b))]
public XPCollection<b> bs { get { GetCollection("bs"); } }
}
public class B : XPObject
{
[Association("a<b") Persistent("Aid")]
public A a { get; set; }
}
ثم عندما تريد ملء قائمة منسدلة (مثل عنصر تحكم lookupEdit)
A myA = GetSomeParticularA();
lupAsBs.Properties.DataSource = myA.Bs;
lupAsBs.Properties.DisplayMember = "WhateverPropertyName";
ليس عليك تحميل أطفال A، وسيقوم XPO بتحميلهم حسب الحاجة، وليس هناك حاجة لإدارة الجلسة لهذا على الإطلاق.
شكرا على الاجابة.لقد قمت بإنشاء حل منفصل وتمكنت من الحصول على أداء جيد، كما تقترح.
اتصال SQL الخاص بي على ما يرام ويعمل مع ميزات أخرى في التطبيق.
نظرًا لأنني أستخدم XAF ولا أفعل أي شيء إضافي/فاخر، ألا تتم إدارة جلساتي بواسطة XAF؟
تتم قراءة الجلسة التي أستخدمها من DetailView.
لست متأكدًا من حالتك، أريد فقط مشاركة بعض تجاربي مع XAF.
في المرة الأولى التي تنقر فيها على عنصر التحكم في القائمة المنسدلة (قائمة البحث) (في عرض التفاصيل)، سيتم إرسال استعلامين إلى قاعدة البيانات لملء القائمة.في اختباراتي، في بعض الأحيان يتم تحميل الكائن بأكمله في المجموعة المصدر، وليس فقط خصائص المعرف والاسم كما اعتقدنا، ويعتمد ذلك على الكائنات الخاصة بك، وقد ترغب في استخدام كائنات أخف للقوائم.يمكنك أيضًا تشغيل وضع الخادم بالقائمة، حيث يتم تحميل 128 كائنًا فقط في كل مرة.