.NET कोर 3.0 एंटिटी फ्रेमवर्क में एक समूह में शामिल होने के लिए कैसे?


13

.NET कोर 3.0 में परिवर्तन के साथ मुझे मिल रहा है

... नेवीगेशनएक्सपैंडिंगExpressionVisitor 'विफल रहा। यह ईएफ कोर में बग या सीमा का संकेत दे सकता है। अधिक विस्तृत जानकारी के लिए https://go.microsoft.com/fwlink/?linkid=2101433 देखें ।) ---> System.InvalidOperationException: LINQ अभिव्यक्ति 'GroupJoin, ... का प्रसंस्करण

यह एक बहुत ही सरल क्वेरी है, इसलिए इसे .NET CORE 3.0 में प्रदर्शन करने का एक तरीका होना चाहिए:

 var queryResults1 = await patients
            .GroupJoin(
                _context.Studies,
                p => p.Id,
                s => s.Patient.Id,
                (p, studies) => new 
                {
                    p.DateOfBirth,
                    p.Id,
                    p.Name,
                    p.Sex,
                   Studies =studies.Select(s1=>s1)
                }
            )
            .AsNoTracking().ToListAsync();

मैं मूल रूप से एक Linq क्वेरी (या ऊपर के रूप में विधि सिंटैक्स) की तलाश कर रहा हूं, जो मरीजों पर अध्ययन में शामिल होगी, और दिए गए रोगी के लिए कोई अध्ययन नहीं होने पर अध्ययनों को एक खाली सूची या अशक्त में सेट करें।

कोई विचार? यह .NET कोर 2.2 में काम कर रहा था। इसके अलावा MSFT लिंक में उल्लेख किया गया है कि महत्वपूर्ण ब्रेकिंग परिवर्तन क्लाइंट साइड मूल्यांकन से संबंधित है और इससे बचने के लिए उत्पन्न क्वेरी पूरे टेबल को पढ़ती है जिसे तब शामिल होना चाहिए या क्लाइंट साइड को फ़िल्टर करना चाहिए। हालाँकि इस सरल क्वेरी के साथ, जुड़ाव आसानी से करने योग्य सर्वर साइड होना चाहिए।

जवाबों:


11

जैसा कि यहां चर्चा की गई है , आप एक क्वेरी का प्रयास कर रहे हैं जो डेटाबेस द्वारा समर्थित नहीं है। EF Core 2 ने आपके कोड को काम करने के लिए क्लाइंट-साइड मूल्यांकन का उपयोग किया, लेकिन EF Core 3 मना कर देता है, क्योंकि क्लाइंट-साइड सुविधा हार्ड-टू-डीबग प्रदर्शन समस्याओं की लागत पर आती है, क्योंकि डेटासेट बढ़ती है।

आप DefaultIfEmptyमरीजों के अध्ययन में बाएं से जुड़ने के लिए उपयोग कर सकते हैं और फिर मैन्युअल रूप से समूह बना सकते हैं ToLookup

var query =
    from p in db.Patients
    join s in db.Studies on p.Id equals s.PatientId into studies
    from s in studies.DefaultIfEmpty()
    select new { Patient = p, Study = s };

var grouping = query.ToLookup(e => e.Patient); // Grouping done client side

उपरोक्त उदाहरण पूर्ण रोगी और अध्ययन संस्थाओं को पकड़ लेता है, लेकिन आप इसके बजाय कॉलम उठा सकते हैं। यदि प्रत्येक अध्ययन के लिए आपको रोगी को जिस डेटा की आवश्यकता है वह बहुत बड़ा है, तो इसमें शामिल किए गए क्वेरी में केवल रोगी आईडी का चयन करें, एक अलग गैर-सम्मिलित क्वेरी में रोगी के बाकी डेटा को क्वेरी करें।


2
उत्तर काम करता है! मुझे लगता है कि क्वेरी ट्रांसलेटर में अभी कुछ काम करना बाकी है। इस तरह एक सरल क्वेरी अनुवाद योग्य होनी चाहिए। 2 टेबल के एक साधारण समूह में शामिल होने के लिए प्रदर्शन के मुद्दे नहीं होने चाहिए क्योंकि एफके / इंडेक्स सही होने पर डेटासेट में वृद्धि होती है। मुझे संदेह है कि कई लोगों के पास टीआईएस मुद्दा होगा, एक 2 टेबल समूह में शामिल होना काफी मानक है और अक्सर उपयोग किया जाने वाला प्रश्न है।
शेल्बीपेरेरा

@ she72 मैं सहमत हूं। ऐसा लगता है कि समस्या इस अंतर से उपजी है कि LINQ और SQL "समूह" कीवर्ड का उपयोग कैसे करते हैं। EF Core को LINQ groupbyको लेफ्ट जॉइन में तब्दील करना चाहिए जहाँ ऐसा करने से उम्मीद से ज्यादा पंक्तियाँ नहीं खींचती हैं। मैंने उसी के अनुसार एक टिप्पणी पोस्ट की ।
एडवर्ड ब्रे

मेरे पास एक अनुवर्ती प्रश्न है, मैं अभी भी यह समझने की कोशिश कर रहा हूं कि इस प्रकार की क्वेरी के लिए समूहन को क्लाइंट साइड करने की आवश्यकता क्यों है, नए LINQ ढांचे की एक सीमा लगती है। ऊपर के मामले के लिए मुझे कोई जोखिम नहीं दिख रहा है जो अप्रत्याशित तरीके से क्लाइंट साइड निष्पादन को धीमा करता है। क्या आप स्पष्ट कर सकते हो?
शेल्बीपेरेरा

1
और एक और अनुवर्ती के रूप में मुख्य चिंता इस बात की है: आपके सुधारित प्रश्न में, जो ग्राहक पक्ष में समूहित करता है यदि मेरे पास प्रति रोगी 1000 अध्ययन हैं, तो मैं प्रत्येक रोगी को DB से 1000 बार लोड कर रहा हूं? क्या इस कार्य को DB में करने और समूहित परिणामों को वापस करने के लिए बाध्य करने का कोई विकल्प है?
शेल्बीपेरेरा

1
@ shev72 डेटाबेस को केवल समूहीकृत करना समझता है, उदाहरण के लिए, प्रति मरीज अध्ययनों की गिनती के साथ रोगियों की एक क्वेरी। डेटाबेस हमेशा एक आयताकार डेटासेट लौटाता है। एक पदानुक्रमित समूह की रचना क्लाइंट द्वारा की जानी चाहिए। आप इसे क्लाइंट-साइड मूल्यांकन या ORM के भाग के रूप में देख सकते हैं । एक पदानुक्रमित समूह में, मूल इकाई डेटा दोहराया जाता है, हालांकि पुन: क्वियर नहीं किया जाता है।
एडवर्ड ब्रे

0

वास्तव में एक ही मुद्दा था और इसके साथ एक बड़ा संघर्ष। यह पता चला है कि .net Core 3.0 विधि सिंटैक्स (अभी तक?) में Join या Groupjoin का समर्थन नहीं करता है। मज़ेदार हिस्सा हालांकि, यह क्वेरी सिंटैक्स में काम करता है।

इसे आज़माएं, यह थोड़ा सा सिंटैक्स के साथ सिंटैक्स क्वेरी है। यह अच्छी तरह से बाईं बाहरी जुड़ाव के साथ सही SQL क्वेरी में अच्छी तरह से अनुवाद करता है और इसे डेटाबेस पर संसाधित किया जाता है। मुझे आपके मॉडल नहीं मिले हैं इसलिए आपको सिंटैक्स की जांच करने की आवश्यकता है ...।

var queryResults1 = 
    (from p in _context.patients
    from s in _context.Studies.Where(st => st.PatientId == p.Id).DefaultIfEmpty()
    select new
    {
        p.DateOfBirth,
        p.Id,
        p.Name,
        p.Sex,
        Studies = studies.Select(s1 => s1)
    }).ToListAsync();

वैसे, विधि सिंटैक के साथ जुड़ें और GroupJoin गैर-कोर फ्रेमवर्क और EF के साथ काम करते हैं। और उस सही क्वेरी का अनुवाद करें जो सर्वर साइड pocessed है
hwmaat

1
अध्ययनों में क्या है। चयन (s1 => s1)
अंकुर अरोरा

मॉडल प्रश्न में शामिल नहीं थे इसलिए मुझे अध्ययन मॉडल का पता नहीं है। मेरा सबसे अच्छा अनुमान है कि यह मॉडल में एक आभासी संग्रह है।
hwmaat
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.