2016-10-06 6 views
5

में प्रश्नों के साथ मैं एक अपेक्षाकृत सरल F# क्वेरी अभिव्यक्ति एक में शामिल होने:leftOuterJoin और `.DefaultIfEmpty()` एफ #

let mdrQuery = 
    query { 
     for header in db.CustomerDetails do 
     leftOuterJoin row in db.MDR_0916 
      on (header.PID = row.PID) into result 
     select (result, header) 
     } 

यह हर header और result देता है, लेकिन एक header के लिए कि row में मेल नहीं है, result केवल एक खाली अनुक्रम है और, जब क्वेरी परिणाम कस्टम प्रकार में पास किए जाते हैं, तो मुझे एक त्रुटि मिलती है कि row में किसी फ़ील्ड से जुड़े एक निर्माता को परिभाषित नहीं किया गया है। यह किसी भी header के लिए समझ में आता है जिसमें row में कोई मिलान नहीं है, null अनुक्रम लौटाया गया है। एक उदाहरण:

mdrQuery |> Seq.head;; 
val it : 
    seq<dbSchema.ServiceTypes.MDR_0916> * dbSchema.ServiceTypes.CustomerDetails 
= (seq [null], CustomerDetails {ACCOUNTMANAGER = null; 
          ACCOUNTSTATUS = "XC"; 
          ADDRESSLINE1 = null; 
          ADDRESSLINE2 = null; 
          ADDRESSLINE3 = null; 
          ADDRESSLINE4 = "123 PIG ROAD"... 

मुझे लगता है इस the leftOuterJoin documentation here की वजह से चारों ओर एक तरह से उपलब्ध न हो। लेकिन, जब मैं मेरी क्वेरी के लिए एक टेम्पलेट के रूप कि उदाहरण का उपयोग करके देखें:

error FS0039: The field, constructor or member 'DefaultIfEmpty' is not defined 

साथ

let mdrQuery = 
    query { 
     for header in db.CustomerDetails do 
     leftOuterJoin row in db.MDR_0916 
      on (header.PID = row.PID) into result 
     for row in result.DefaultIfEmpty() do 
     select (result, header) 
     } 

.DefaultIfEmpty() टुकड़ा त्रुटियों बाहर है वहाँ एक रास्ता है कि मैं इस में शामिल होने के होने बना सकते हैं औरresult में None (या कुछ अन्य शून्य SQL शून्य मूल्य) के साथ बेजोड़ पंक्तियों को भरने, प्रत्येक पंक्ति का चयन करें ताकि क्वेरी की संपूर्णता मेरे रिकॉर्ड प्रकार में पारित की जा सके?

आदर्श रूप में, एक बेजोड़ पंक्ति के लिए निर्गम (छोटा कर दिया नीचे हाथ द्वारा बनाई परिणाम)

mdrQuery |> Seq.head;; 
val it : 
    seq<dbSchema.ServiceTypes.MDR_0916> * dbSchema.ServiceTypes.CustomerDetails 
= (MDR_0916 {AIMExp = null; 
     AP = null; 
     APComp = null; 
     APEng = null; 
     APFine = null; 
     APForl = null;...}, 
CustomerDetails {ACCOUNTMANAGER = null; 
          ACCOUNTSTATUS = "XC"; 
          ADDRESSLINE1 = null; 
          ADDRESSLINE2 = null; 
          ADDRESSLINE3 = null; 
          ADDRESSLINE4 = "123 PIG ROAD"... 

संपादित की तरह कुछ होगा:This question/answer मेरा के समान है लेकिन ToOption result सहित बस एक Some (seq [null]) आउटपुट।

+1

आपके इंटरैक्टिव आउटपुट में, 'परिणाम' खाली अनुक्रम नहीं है, बल्कि एक तत्व का अनुक्रम है, और वह तत्व 'शून्य' है। –

+0

स्पष्टीकरण के लिए धन्यवाद। – Steven

+4

'DefaultIfEmpty' एक विस्तार विधि है, इसलिए आपको 'System.Linq' खोलने की आवश्यकता है। – kvb

उत्तर

0

दस्तावेज़ीकरण गलत है; सी # में leftOuterJoin ऑपरेटर का कोई प्रत्यक्ष समतुल्य नहीं है, इसलिए DefaultIfEmpty का उपयोग सामान्य जुड़ने के साथ किया जाता है, लेकिन F # में आपको इसकी आवश्यकता नहीं होती है (क्वेरी बिल्डर आपके लिए यह अनुवाद करता है - में देखें यदि आप उत्सुक हैं)।

आप में शामिल है, तो बस अतिरिक्त for पाश DefaultIfEmpty बिना (लेकिन ध्यान दें - आप नव बाध्य row मान का चयन करना चाहते हैं, नहींresult अनुक्रम) जोड़ने के एक पारंपरिक बाईं के परिणाम चाहते हैं:

let mdrQuery = 
    query { 
     for header in db.CustomerDetails do 
     leftOuterJoin row in db.MDR_0916 
      on (header.PID = row.PID) into result 
     for row in result do 
     select (row, header) 
    } 

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

+0

'null' फ़ील्ड मानों के साथ' MDR_0916' मान बनाने के लिए पोस्ट प्रोसेसिंग चरण लागू करने के सुझाव के लिए शानदार उत्तर और धन्यवाद। मैंने केवल 'एमडीआर ...' से उन क्षेत्रों का चयन करना समाप्त कर दिया है, जिन्हें मुझे एक कस्टम प्रकार में पारित करने की आवश्यकता है और फिर से लिखना है। – Steven

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