2013-01-17 587 views
8

मेरे पास एक अलग फ्रेमवर्क परियोजना है जिसमें 5 अलग-अलग टेबल हैं। जब मैं इन तालिकाओं से डेटा पूछता हूं और .Include() का उपयोग करता हूं, तो यह उत्पन्न क्वेरी बहुत धीमी और समय समाप्त होती है।मैं अपनी ईएफ linq क्वेरी को संग्रहीत प्रक्रिया में बदल रहा हूं। जटिल मैपिंग सेट अप करने का कोई आसान तरीका है?

मैं एक संग्रहीत प्रक्रिया के लिए क्वेरी स्थानांतरित कर दिया है, और अब एक तरह से इस संग्रहीत प्रक्रिया क्वेरी, और आसानी से मैप करने के लिए डेटा यह मौजूदा डेटा वर्गों के लिए रिटर्न के लिए देख रहा हूँ।

var data = (from a in context.A 
        .Include("B") 
        .Include("C") 
        .Include("D") 
        .Include("E") 
      where a.Id == someValue 
      select a); 

यह एक इकाई डेटा उद्देश्य यह है कि इस मची वापसी:

एफई के DataContext मेरे मूल LINQ क्वेरी इस तरह देखा

class A 
{ 
    int Id; 
    string otherProperties; 

    List<B> B; 
    List<C> C; 
    List<D> D; 
    List<E> E; 
} 

क्वेरी कि SQL सर्वर पर चलाने के लिए लौट आए उत्पन्न एफई एक परिणाम सेट जो इस तरह कुछ दिखता है:

 
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 
---------------------------------------------------------- 
A1 A2 B1 B2   
A1 A2    C1 C2 
A1 A2    C1 C2 
A1 A2    C1 C2 
A1 A2       D1 D2 
A1 A2       D1 D2 
A1 A2       D1 D2 
A1 A2          E1 E2 
A1 A2          E1 E2 

(अनुमान 1 बी रिकॉर्ड, 3 सी रिकॉर्ड, 3 डी रिकॉर्ड, और 2 ई रिकॉर्ड।

मैंने इस क्वेरी को संग्रहीत प्रक्रिया में पुन: उत्पन्न किया है और इसके रनटाइम को व्यावहारिक रूप से कुछ भी कम नहीं किया है, हालांकि मैं अपने एंटिटी फ्रेमवर्क डेटा क्लास (क्लास A ऊपर से) के परिणाम सेट को मैप करने का तरीका जानने के लिए अटक गया हूं।

ईएफ निश्चित रूप से इस में सक्षम है क्योंकि यह लिंक क्वेरी का उपयोग करते समय दृश्यों के पीछे कहीं भी है, लेकिन मुझे यकीन नहीं है कि अगर ऐसा कुछ है तो मुझे इसका उपयोग होगा।

वहाँ इकाई की रूपरेखा में एक आसान तरीका एक बहु स्तरीय इकाई की रूपरेखा वर्ग के लिए एक भी संग्रहीत प्रक्रिया (फंक्शन आयात) मैप करने के लिए है?

उत्तर

2

मैं एक ब्लॉग पोस्ट बताते हैं कि यह कैसे इकाई की रूपरेखा के साथ किया जा सकता है पाया।

http://blogs.infosupport.com/ado-net-entity-framework-advanced-scenarios-working-with-stored-procedures-that-return-multiple-resultsets/

यह संक्षिप्त संक्षेप में, आप तो यह एक विशिष्ट तरीका है कि इकाई की रूपरेखा द्वारा की उम्मीद है में अपने डेटा को देता है अपने संग्रहीत प्रक्रिया लिखने के लिए की जरूरत है, और उसके बाद आप अपने संग्रहीत प्रक्रिया निष्पादन अनुकूलित करने के लिए कुछ EF extensions उपयोग कर सकते हैं , और अपने ऑब्जेक्ट ग्राफ़ को मूर्त रूप देने के लिए।

ऐसा लगता है कि यह भविष्य के संस्करणों (5.0+ मुझे विश्वास है) में एंटीटी फ्रेमवर्क में बनाया गया है, हालांकि यह कामकाज ऐसा लगता है कि इसे निम्न संस्करणों के लिए काम करना चाहिए।

हालांकि मेरे मामले में, मैंने पाया कि अगर मैंने अपनी लिंक क्वेरी में .Include() से छुटकारा पा लिया है और ऑब्जेक्ट लौटने से पहले कोड में संदर्भित करके मैन्युअल रूप से अन्य गुणों को लोड करने के लिए ट्रिगर किया है, तो प्रदर्शन के साथ मेरी समस्या ठीक हो गई है। इसका कारण यह है कि 5 टेबलों के बीच एक बड़े पैमाने पर पूछताछ के बजाय अनपेक्षित जुड़ने के बजाय, यह 5 अलग-अलग प्रश्नों को चलाता है जो प्रत्येक केवल विशिष्ट डेटा को खींचता है।

1

जब मैं एक महंगी क्वेरी को एक संग्रहित प्रसंस्करण में परिवर्तित करके EntityFramework को अनुकूलित कर रहा हूं, तो मैं परिणामों के लिए एक कस्टम क्लास बनाता हूं और फिर मेरी कस्टम क्लास को इकाइयों में परिवर्तित करने के लिए डीबीकॉन्टेक्स्ट में कुछ तर्क करता हूं।

तो तुम में अपने DbContext

public A GetA(int ID) 
{ 
// do stored procedure 
IEnumerable<StoreProcARow> procResult = ... 
// process procResult into A type 

} 
+0

यदि ईएफ में कोई आसान विकल्प नहीं बनाया गया तो यह मेरी बैकअप योजना थी। प्रत्येक वर्ग पर बहुत सारी संपत्तियां हैं, इसलिए कनवर्टर को कोड करने के लिए यह बहुत अधिक टाइपिंग होगा। – Rachel

0

प्रयास करें AutoMapper तरह

public class StoreProcARow 
{ 
public string Name {get;set;} // properties for every column 
} 

और फिर कुछ बनाएंगे।

using AutoMapper; 

... 

Mapper.CreateMap<DataModel.B, ReplyObjects.B>; 
Mapper.CreateMap<DataModel.C, ReplyObjects.C>; 
... 
return new A 
{ 
    B = Mapper.Map<DataModel.B, ReplyObjects.B>(varContainingDataForB), 
    C = Mapper.Map<DataModel.C, ReplyObjects.C>(varContainingDataForC) 
    ... 
}; 

जब तक आपके ReplyObjects.B में गुण नाम और DataModel.B के प्रकार का मिलान नहीं हुआ, सब कुछ अपने आप नक्शा होगा:

आप की तरह कुछ करना चाहते हैं!

+0

शायद यह मेरे मामले में काम नहीं करेगा, क्योंकि मेरे प्रारंभिक डेटा सेट में पूरे ऑब्जेक्ट ग्राफ़ के लिए सभी डेटा शामिल हैं, और कई गुणों को वास्तव में वही नाम दिया जाता है (जैसे 'आईडी')। – Rachel