المساعدة اللازمة لتحسين linq استخراج البيانات
-
22-07-2019 - |
سؤال
أنا جلب البيانات من جميع 3 الجداول مرة واحدة لتجنب استتار شبكة الاتصال.جلب البيانات سريع جدا, ولكن عندما الحلقة من خلال النتائج الكثير من الوقت
Int32[] arr = { 1 };
var query = from a in arr
select new
{
Basket = from b in ent.Basket
where b.SUPERBASKETID == parentId
select new
{
Basket = b,
ObjectTypeId = 0,
firstObjectId = "-1",
},
BasketImage = from b in ent.Image
where b.BASKETID == parentId
select new
{
Image = b,
ObjectTypeId = 1,
CheckedOutBy = b.CHECKEDOUTBY,
firstObjectId = b.FIRSTOBJECTID,
ParentBasket = (from parentBasket in ent.Basket
where parentBasket.ID == b.BASKETID
select parentBasket).ToList()[0],
},
BasketFile = from b in ent.BasketFile
where b.BASKETID == parentId
select new
{
BasketFile = b,
ObjectTypeId = 2,
CheckedOutBy = b.CHECKEDOUTBY,
firstObjectId = b.FIRSTOBJECTID,
ParentBasket = (from parentBasket in ent.Basket
where parentBasket.ID == b.BASKETID
select parentBasket),
}
};
//Exception handling
var mixedElements = query.First();
ICollection<BasketItem> basketItems = new Collection<BasketItem>();
//Here 15 millis has been used
//only 6 elements were found
if (mixedElements.Basket.Count() > 0)
{
foreach (var mixedBasket in mixedElements.Basket){}
}
if (mixedElements.BasketFile.Count() > 0)
{
foreach (var mixedBasketFile in mixedElements.BasketFile){}
}
if (mixedElements.BasketImage.Count() > 0)
{
foreach (var mixedBasketImage in mixedElements.BasketImage){}
}
//the empty loops takes 811 millis!!
المحلول
لماذا يكلف نفسه عناء التحقق من التهم قبل foreach التصريحات ؟ إذا كان هناك أي نتائج ، foreach سوف أنهي على الفور.
الاستفسارات الخاصة بك هي في الواقع كل ما يجري المؤجلة - سوف يتم تنفيذها عندما تسأل عن البيانات.لا ننسى أن الأبعد الاستعلام هو LINQ إلى كائنات الاستعلام:انها مجرد العودة نتيجة الدعوة ent.Basket.Where(...).Select(...)
الخ...التي لا فعلا تنفيذ الاستعلام.
الخطة الخاصة بك أن تفعل كل ثلاثة استفسارات في دفعة واحدة لا تعمل في الواقع.ومع ذلك, قبل طلب الاعتماد بشكل منفصل ، قد يكون في الواقع تنفيذ كل قاعدة بيانات الاستعلام مرتين - مرة واحدة فقط الحصول على الاعتماد ومرة النتائج.
أقترح بشدة أن تحصل على التخلص من "تحسينات" في هذه المدونة التي هي مما يجعلها أكثر تعقيدا من ذلك بكثير ، أبطأ من مجرد الكتابة أبسط كود يمكنك.
أنا لا أعرف أي طريقة للحصول على LINQ to SQL (أو ينق ل EF) لتنفيذ استعلامات متعددة في مكالمة واحدة - ولكن هذا النهج بالتأكيد لن تفعل ذلك.
واحد الطفيفة الأخرى التلميح الذي يهم في هذه الحالة ، ولكن يمكن أن تكون مفيدة في LINQ إلى الأشياء - إذا كنت ترغب في معرفة ما إذا كان هناك أية بيانات في مجموعة, مجرد استخدام Any()
بدلا من Count() > 0
- أن هذه الطريقة يمكن أن تتوقف في أقرب وقت كما انها وجدت أي شيء.
نصائح أخرى
وإنك تستخدم IEnumerable
في حلقة foreach. يكون التنفيذ فقط لإعداد البيانات عندما يكون طلب من أجله. وبهذه الطريقة، أنا أقترح أن رمز أعلاه يتم الوصول إلى البيانات الخاصة بك بتكاسل - وهذا هو، فقط عند تعداد العناصر
Count()
).
ووضع System.Diagnostics.Stopwatch
حول الدعوة إلى Count()
ومعرفة ما إذا كان هذا ما أخذ الجزء الأكبر من وقت ترونه.
لا أستطيع التعليق مزيد من هنا لأنك لم تحدد نوع ent
في نموذج التعليمات البرمجية الخاصة بك.