2008-09-18 9 views
5

एक गैर-सी # समझदार प्रोग्रामर के रूप में बोलते हुए, मैं निम्नलिखित जैसे LINQ प्रश्नों के मूल्यांकन अर्थशास्त्र के लिए उत्सुक हूं:LINQ-to-SQL समर्थन कंपोज़ेबल क्वेरीज़ करता है?

var people = from p in Person 
      where p.age < 18 
      select p 

var otherPeople = from p in people 
        where p.firstName equals "Daniel" 
        select p 

मानते हैं कि Person एक एडीओ इकाई है जो age और firstName फ़ील्ड को परिभाषित करता है, क्या होगा यह डेटाबेस दृष्टिकोण से करते हैं? विशेष रूप से, people क्वेरी को इन-मेमोरी स्ट्रक्चर बनाने के लिए चलाया जाएगा, जिसे otherPeople क्वेरी द्वारा क्वेरी किया जाएगा? या otherPeople का निर्माण केवल people से क्वेरी के बारे में डेटा खींच लेगा और फिर एक नया डेटाबेस-सहकर्मी क्वेरी तैयार करेगा? इसलिए, यदि मैं इन दोनों प्रश्नों पर पुन: प्रयास करता हूं, तो कितने SQL कथन निष्पादित किए जाएंगे?

उत्तर

12

वे composable हैं। यह संभव है क्योंकि LINQ प्रश्न वास्तव में अभिव्यक्ति (डेटा के रूप में कोड) हैं, जो LINQ-to-SQL जैसे LINQ प्रदाता मूल्यांकन कर सकते हैं और संबंधित SQL उत्पन्न कर सकते हैं।

क्योंकि LINQ प्रश्नों का आलसी मूल्यांकन किया जाता है (उदाहरण के लिए जब तक आप तत्वों पर पुनरावृत्ति नहीं करते हैं तब तक निष्पादित नहीं किया जाएगा), आपके द्वारा दिखाया गया कोड वास्तव में डेटाबेस को स्पर्श नहीं करेगा। जब तक आप अन्य लोगों या लोगों पर पुनरावृत्ति नहीं करेंगे तब तक एसक्यूएल जेनरेट और निष्पादित नहीं होगा।

1

people और otherPeople में IQueryable<Person> प्रकार की वस्तुएं शामिल हैं।

यदि आप अलग-अलग दोनों पर पुनरावृत्त करते हैं, तो यह दो प्रश्नों को चलाएगा। यदि आप केवल otherPeople से अधिक सक्रिय करते हैं, तो यह दो क्वेरी के साथ अपेक्षित क्वेरी चलाएगा।

आप people पर .ToList() करते हैं और वापस आ List<Person> बजाय लोगों की दूसरी क्वेरी में उपयोग करते हैं, यह LINQ करने वाली वस्तुओं हो जाता है और कोई एसक्यूएल निष्पादित किया जाता है।

इस व्यवहार को स्थगित निष्पादन के रूप में जाना जाता है। इसका मतलब है कि जब तक इसकी आवश्यकता नहीं होती है तब तक कोई प्रश्न नहीं किया जाता है। निष्पादन से पहले वे केवल अभिव्यक्ति पेड़ हैं जो अंतिम क्वेरी तैयार करने के लिए छेड़छाड़ करते हैं।

0

इन दोनों प्रश्नों को निष्पादित किया जाएगा जब आप अंतिम परिणामों तक पहुंचने का प्रयास करेंगे। आप DataContext ऑब्जेक्ट गुणों से उत्पन्न मूल SQL को देखने का प्रयास कर सकते हैं।

3

हां, परिणामी क्वेरी तैयार की गई है। इसमें पूर्ण जहां खंड शामिल है। एसक्यूएल प्रोफाइलिंग चालू करें और अपने आप को देखने के लिए इसे आजमाएं।

लिंक यह अभिव्यक्ति पेड़ों के माध्यम से करता है। पहला linq कथन एक अभिव्यक्ति पेड़ पैदा करता है; यह क्वेरी निष्पादित नहीं करता है। दूसरा linq कथन पहले द्वारा बनाई गई अभिव्यक्ति वृक्ष पर बनाता है। कथन केवल तभी निष्पादित होता है जब आप परिणामस्वरूप संग्रह की गणना करते हैं।

3
var people = from p in Person 
      where p.age < 18 
      select p 

अनुवाद करता है:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName] 
FROM [dbo].[Person] AS [t0] 
WHERE [t0].[Age] < @p0 

जहां @ p0 के रूप में 18

var otherPeople = from p in people 
        where p.firstName equals "Daniel" 
        select p 

के माध्यम से भेजा जाता है वास्तविक रूप है:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName] 
FROM [dbo].[Person] AS [t0] 
WHERE [t0].[FirstName] = @p0 

जहां @ p0 के रूप में के माध्यम से भेजा जाता है " डैनियल "

var morePeople = from p1 in people 
       from p2 in otherPeople 
       where p1.PersonId == p2.PersonId 
       select p1; 

अनुवाद करता है:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName] 
FROM [dbo].[Person] AS [t0], [dbo].[Person] AS [t1] 
WHERE ([t0].[PersonId] = [t1].[PersonId]) AND ([t0].[Age] < @p0) AND ([t1].[FirstName] = @p1) 

जहां @ p0 18 है, @ p1 है "डैनियल"

संदेह होने पर, अपने IQueryable पर toString() पर कॉल करें या करने के लिए एक TextWriter देना DataContext की लॉग संपत्ति।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^