क्या linq का कीवर्ड अपने कीवर्ड से बेहतर है?


86

मैं वर्तमान में LINQ पर ब्रश कर रहा हूं letऔर intoकीवर्ड के उपयोग और उसके बीच के अंतर को समझने की कोशिश कर रहा हूं । अब तक letकीवर्ड intoमेरी समझ से बेहतर है, जहां तक ​​मेरी समझ जाती है।

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

नामों की एक सरणी को देखते हुए यह निम्नलिखित को करने की अनुमति देता है:

var intoQuery =
  from n in names
  select Regex.Replace(n, "[aeiou]", "")
  into noVowel
  where noVowel.Length > 2
  select noVowel;

यह चयन का परिणाम लेता है और में यह स्थानों noVowelचर जो तब एक अतिरिक्त पेश करने की अनुमति देता है where, orderbyऔर selectखंड। एक बार noVowelचर बनाने के बाद, चर nअब उपलब्ध नहीं है।

letकीवर्ड, दूसरे हाथ पर, अस्थायी गुमनाम प्रकार का उपयोग करता है आप एक समय में एक से अधिक चर का पुन: उपयोग करने की अनुमति।

आप निम्न कार्य कर सकते हैं:

var letQuery =
  from n in names
  let noVowel = Regex.Replace(n, "[aeiou]", "")
  where noVowel.Length > 2
  select noVowel;

दोनों चर noVowelऔर nचर उपयोग के लिए उपलब्ध हैं (भले ही मैंने इस मामले में इसका उपयोग नहीं किया है)।

जब मैं अंतर देख सकता हूं, तो मैं यह नहीं समझ सकता कि कोई व्यक्ति intoकीवर्ड पर कीवर्ड का उपयोग क्यों करना चाहेगा letजब तक कि कोई स्पष्ट रूप से यह सुनिश्चित नहीं करना चाहता था कि पिछले चर क्वेरी के बाद के भागों में उपयोग करने में सक्षम नहीं थे।

तो, क्या कोई अच्छा कारण है कि दोनों कीवर्ड मौजूद हैं?


क्या यह letउदाहरण में एक टाइपो है - उस मामले में where noVowelक्या है noVowel?
sll

जवाबों:


85

हां, क्योंकि वे अलग-अलग चीजें कर रहे हैं, जैसा कि आपने कहा है।

select ... intoप्रभावी ढंग से पूरे एक क्वेरी को अलग करता है और आपको इसे एक नई क्वेरी के इनपुट के रूप में उपयोग करने देता है। व्यक्तिगत रूप से मैं आमतौर पर दो चर के माध्यम से ऐसा करना पसंद करता हूं:

var tmp = from n in names
          select Regex.Replace(n, "[aeiou]", "");

var noVowels = from noVowel in tmp
               where noVowel.Length > 2
               select noVowel;

(निश्चित रूप से इस मामले में मैं इसे दो पंक्तियों में डॉट नोटेशन के साथ करूंगा, लेकिन उस पर ध्यान नहीं देते ...)

अक्सर आप क्वेरी के पहले भाग के पूरे सामान को नहीं चाहते हैं - जब आप select ... intoउपरोक्त उदाहरण के अनुसार दो में क्वेरी का उपयोग या विभाजन करते हैं। इतना ही नहीं इसका मतलब यह नहीं है कि क्वेरी के पहले के हिस्सों का उपयोग तब नहीं किया जा सकता है जब उन्हें नहीं होना चाहिए, यह सरल करता है कि क्या चल रहा है - और निश्चित रूप से इसका मतलब है कि प्रत्येक चरण पर संभावित कम प्रतिलिपि चल रही है।

दूसरी ओर, जब आप करते संदर्भ के बाकी रखना चाहते हैं, letअधिक समझ में आता है।


9
क्या एक या दूसरे का उपयोग उत्पन्न SQL को प्रभावित करता है?
पैट नीमेयर

44

प्राथमिक अंतर letचर को संदर्भ / दायरे में इंजेक्ट करता है, जहां intoएक नया संदर्भ / गुंजाइश बनाता है।


1

DB साइड पर अंतर जानना चाहते हैं, 2 एंटिटी फ्रेमवर्क क्वेरी लिखी हैं।

  • चलो

    from u in Users
    let noVowel = u.FirstName.Replace("a","").Replace("e","").Replace("i","")
    where noVowel.Length >5
    select new {u.FirstName, noVowel}
    
  • में

    from u in Users
    select u.FirstName.Replace("a","").Replace("e","").Replace("i","")
    into noVowel
    where noVowel.Length >5
    select noVowel
    

उत्पन्न SQL लगभग समान हैं । SQL सही नहीं है, समान स्ट्रिंग प्रक्रिया कोड 2 स्थानों (जहां और चुनें) पर दोहराया जाता है।

SELECT 1 AS [C1], [Extent1].[FirstName] AS [FirstName], 
REPLACE(REPLACE(REPLACE([Extent1].[FirstName], N'a', N''), N'e', N''), N'i', N'') AS [C2]
FROM [dbo].[User] AS [Extent1]
WHERE ( CAST(LEN(REPLACE(REPLACE(REPLACE([Extent1].[FirstName], N'a', N''), N'e', N''), N'i', N'')) AS int)) > 5
GO

SELECT 
REPLACE(REPLACE(REPLACE([Extent1].[FirstName], N'a', N''), N'e', N''), N'i', N'') AS [C1]
FROM [dbo].[User] AS [Extent1]
WHERE ( CAST(LEN(REPLACE(REPLACE(REPLACE([Extent1].[FirstName], N'a', N''), N'e', N''), N'i', N'')) AS int)) > 5

यहाँ LINQ-to-SQL द्वारा उत्पन्न SQL है

-- Region Parameters
DECLARE @p0 NVarChar(1000) = 'a'
DECLARE @p1 NVarChar(1000) = ''
DECLARE @p2 NVarChar(1000) = 'e'
DECLARE @p3 NVarChar(1000) = ''
DECLARE @p4 NVarChar(1000) = 'i'
DECLARE @p5 NVarChar(1000) = ''
DECLARE @p6 Int = 5
-- EndRegion
SELECT [t1].[FirstName], [t1].[value] AS [noVowel]
FROM (
    SELECT [t0].[FirstName], REPLACE(REPLACE(REPLACE([t0].[FirstName], @p0, @p1), @p2, @p3), @p4, @p5) AS [value]
    FROM [User] AS [t0]
    ) AS [t1]
WHERE LEN([t1].[value]) > @p6
GO

-- Region Parameters
DECLARE @p0 NVarChar(1000) = 'a'
DECLARE @p1 NVarChar(1000) = ''
DECLARE @p2 NVarChar(1000) = 'e'
DECLARE @p3 NVarChar(1000) = ''
DECLARE @p4 NVarChar(1000) = 'i'
DECLARE @p5 NVarChar(1000) = ''
DECLARE @p6 Int = 5
-- EndRegion
SELECT [t1].[value]
FROM (
    SELECT REPLACE(REPLACE(REPLACE([t0].[FirstName], @p0, @p1), @p2, @p3), @p4, @p5) AS [value]
    FROM [User] AS [t0]
    ) AS [t1]
WHERE LEN([t1].[value]) > @p6

लगता है Linq-to-SQL एंटिटी फ्रेमवर्क की तुलना में अधिक स्मार्ट है, स्ट्रिंग प्रक्रिया केवल एक बार की जाती है।


0

लेपी के उत्तर का दृश्य संस्करण । जैसा कि देखा जा सकता है, कंपाइलर intoउत्तरार्द्ध में पहले वाले वेरिएबल तक पहुंचने के साथ त्रुटि देता है ।

यहां छवि विवरण दर्ज करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.