2011-03-01 15 views
8

मैं बुनियादी LINQ के संचालन के लिए विस्तार तरीकों का उपयोग करना पसंद करते हैं: Where(), Select, लेकिन जटिल Select(), SelectMany(), और विशेष रूप OrderBy().ThenBy() बयानों के लिए मैं क्वेरी सिंटैक्स और अधिक पठनीय और प्राकृतिक होने के लिए लगता है।Linq मिश्रण विस्तार और क्वेरी सिंटैक्स

आज मैं निम्न क्वेरी के साथ अपने आप को पाया:

from c in _myObject.ObjectsParent.ParentsEnumerable 
        .Where(c => 
         c == anotherObject || c.Parent == anotherObject) 
from q in c.MyObjectsEnumerable 
orderby c.SortKey, q.Description 
select new { Item = q, Text = c.Description + " -> " + q.Description }; 

यह है खतरनाक क्वेरी और विस्तार वाक्य रचना मिश्रण (पठनीयता, रख-रखाव, या किसी अन्य कारण के लिए)?

यह बहुत ही व्यक्तिपरक होने की संभावना है, अगर ऐसा है, तो मुझे खेद है कि यह एक अच्छे व्यक्तिपरक प्रश्न के लिए आवश्यकताओं को पूरा नहीं करता है। अगर मैं इसे सुधार सकता हूं तो मुझे बताएं!

उत्तर

6

क्या यह खतरनाक (पठनीयता, रखरखाव, या किसी अन्य कारण के लिए) क्वेरी और एक्सटेंशन वाक्यविन्यास मिश्रण करने के लिए है?

सबसे बड़ा खतरा जो मैं देखता हूं वह आपके कोड में "आश्चर्य" का संभावित जोड़ है, खासकर जब अन्य डेवलपर्स द्वारा देखा जाता है।

संकलन दृष्टिकोण से, क्वेरी सिंटैक्स का सीधे विस्तार विधि कॉल में अनुवाद किया जाता है, इसलिए यहां कोई तकनीकी समस्या नहीं है। हालांकि, यह संभावित रूप से अतिरिक्त विधि कॉल जोड़ने जा रहा है जो कि पहली नज़र में, कई डेवलपर्स द्वारा अपेक्षित नहीं होंगे। यह संभावित रखरखाव समस्या का कारण बन सकता है।

कहा जा रहा है कि, यदि कम से कम और अच्छे कारण से किया गया है, तो मुझे नहीं लगता कि वाक्यविन्यास को मिलाकर वास्तविक समस्या है। यह वास्तव में काफी आम है - उदाहरण के लिए, यदि आप क्वेरी सिंटैक्स में लिखना चाहते हैं, लेकिन पूरी तरह से मूल्यांकन करने की आवश्यकता है, तो इसे अक्सर कोष्ठक में लपेटा जाता है। टोस्टिस्ट() जोड़ा गया - या यदि आप क्वेरी सिंटैक्स के साथ PLINQ का उपयोग करना चाहते हैं, तो यह अक्सर from x in collection.AsParallel() होता है , जो तकनीकी रूप से सिंटैक्स मिश्रण कर रहा है ...

+0

धन्यवाद, यह मेरे ज्यादातर विचारों और चिंताओं का सबसे अधिक उत्तर दिया गया है। – Crisfole

3

आप चीजों को थोड़ा आसान बनाने के लिए ऐसा कुछ कर सकते हैं।

var firstQuery = _myObject.ObjectsParent.ParentsEnumerable 
       .Where(c => c == anotherObject || c.Parent == anotherObject); 

var secondQuery = from q in firstQuery.MyObjectsEnumerable 
        orderby firstQuery.SortKey, q.Description 
        select new { Item = q, 
           Text = firstQuery.Description + " -> " + q.Description }; 

अब आपके प्रश्नों मिश्रित नहीं कर रहे हैं

+1

पहली पंक्ति ग़लत है ... तुम "में से ग" ड्रॉप चाहिए ... –

+0

मुझे लगता है कि @ रीड-Copsey mean't (* नहीं होना चाहिए) firstQuery क्योंकि नहीं है संपत्ति विवरण इसका केवल एक तत्व होगा। तो यह कोड काम नहीं करता है। – jbtule

1

मैं विस्तार तरीकों का उपयोग, मेरे सहकर्मी क्वेरी सिंटैक्स का उपयोग करता है। इसमें कोई फर्क नही है।

हालांकि मैं कहूंगा कि आपको डिबगिंग और पठनीयता के लिए छोटे से बड़े प्रश्नों को तोड़ना चाहिए क्योंकि आमतौर पर कोई समय लागत नहीं होती है।

1

यह स्वयं करने के बाद (हालांकि नहीं। जहां, लेकिन के लिए।) मैं कहूंगा कि यह बहुत अधिक निर्भर करता है कि आप किस एक्सटेंशन विधियों को बुला रहे हैं।

उदा। मुझे पूरी तरह से उपयोग करने का हकदार महसूस हुआ। क्योंकि यह सिंटैक्टिक चीनी (AFAIK) में उपलब्ध नहीं था, लेकिन शायद इससे बचें। जहां, क्योंकि क्वेरी सिंटैक्स में इसका प्रतिनिधित्व है।

ऐसा कहकर, मैं शायद उपयोग करूँगा। क्वेरी में डेटा को म्यूट करने के लिए भी चयन करें ... लेकिन मैं एक दुखद हूं।

3

यह एक तरह का निर्णय कॉल है, लेकिन कई "सर्वोत्तम अभ्यास" -प्रकार प्रश्न कम से कम पहले होते हैं। मेरी राय यह है कि आपको एक या दूसरे को एक ही कथन के भीतर उपयोग करना चाहिए। मिश्रण में अंतर्निहित किसी भी "खतरे" के लिए वास्तव में नहीं, बल्कि स्पष्टता के लिए।

इस विशेष मामले में, जहां खंड बहुत सरल है, और मैं इसे क्वेरी वाक्यविन्यास में दोबारा प्रतिक्रिया दूंगा।

ऐसे मामले हैं जिन्हें क्वेरी सिंटैक्स में स्पष्ट रूप से व्यक्त नहीं किया जा सकता है। ऐसे मामलों में जहां यह सिंटैक्स मिश्रण करने के लिए बस अपरिहार्य है, प्रश्नों (फिर से आईएमओ) अधिक पठनीय होंगे यदि आप विधि श्रृंखला को अपने चर में विभाजित करते हैं, तो क्वेरी-सिंटैक्ड कथन में उस चर को संदर्भित किया जाता है।

//The method chain can be pulled out as its own variable... 
var filteredParents = _myObject.ObjectsParent.ParentsEnumerable 
        .Where(c => c == anotherObject || c.Parent == anotherObject); 

//...which you can then substitute in a now purely query-syntax statement 
from c in filteredParents 
from q in c.MyObjectsEnumerable 
orderby c.SortKey, q.Description 
select new { Item = q, Text = c.Description + " -> " + q.Description }; 
2

मैं, नहीं लगता कि यह मिश्रण करने खतरनाक है कि यह यह क्या अधिक पठनीय है, क्वेरी सिंटैक्स बहुत पठनीय है, लेकिन नहीं के रूप में flexable है, इसलिए मिश्रण कुछ श्रृंखलन एक की तरह लगता है पर निर्भर करता है लगता है: एक मॉडल के रूप तुम्हारा का उपयोग करना भुगतान करने के लिए छोटी कीमत। मुझे लगता है कि जवाब यह है कि क्या आपको लगता है कि निम्नलिखित पूरी तरह से जंजीरों को और अधिक पठनीय है जिसे आपने लिखा था, मैं व्यक्तिगत रूप से सोचता हूं कि आपका पढ़ने के लिए आसान है।

_myObject.ObjectsParent 
      .ParentsEnumerable 
      .Where(c => c == anotherObject || c.Parent == anotherObject) 
      .SelectMany(c => c.MyObjectsEnumerable, (c, q) => new {c, q}) 
      .OrderBy(t => t.c.SortKey) 
      .ThenBy(t => t.q.Description) 
      .Select(t => new {Item = t.q, Text = t.c.Description + " -> " + t.q.Description}); 
संबंधित मुद्दे