मेरे पास एक कार्य विधि-आधारित क्वेरी है जो इस तरह दिखती है:

string param = request.QRBarang.Split('~')[1];
var a = await _db.A.FirstOrDefaultAsync(a => a.IdA == param);
var b = await _db.B.FirstOrDefaultAsync(b => b.IdB1 == a.IdA);
var c = await _db.C.FirstOrDefaultAsync(c => c.IdC1 == b.IdB2);
var d = c != null
         ? await _db.D.FirstOrDefaultAsync(d => d.IdD == c.IdC2)
         : null;
var dto = new DTOFin { ...};

मैं अभी भी LINQ सीख रहा हूं और सिंटैक्स को क्वेरी एक्सप्रेशन में बदलने की कोशिश कर रहा हूं, लेकिन सी का मान शून्य होने पर हमेशा त्रुटि मिलती है। यहाँ मेरी कोशिश है:

var dto = (from a in _db.A
           join b in _db.B on a.IdA equals b.IdB1
           join c in _db.C on b.IdB2 equals c.IdC1
           join d in _db.D on c.IdC2 equals d.IdD
           where a.IdA == param && object.Equals(c.IdC2, d.IdD)
           select new DTOFin { ...}).FirstOrDefaultAsync();

मैंने join c in _db.C on b.IdB2 equals c?.IdC1 का उपयोग करने का भी प्रयास किया लेकिन उत्पादन किया

त्रुटि CS8072 एक एक्सप्रेशन ट्री लैम्ब्डा में एक नल प्रोपेगेटिंग ऑपरेटर नहीं हो सकता है।

मुझे क्वेरी एक्सप्रेशन के बराबर पहला सिंटैक्स कैसे लिखना चाहिए?

1
Billy Joseph 1 सितंबर 2021, 04:47

2 जवाब

सबसे बढ़िया उत्तर

मान लें कि आपके पास नेविगेशन गुण सही तरीके से कॉन्फ़िगर किए गए हैं तो यह काम करना चाहिए:

(मैं ध्यान देता हूं कि EF6 और EF Core के मचान टेम्प्लेट (मौजूदा डेटाबेस से ऑटो-जेनरेटिंग एंटिटी क्लासेस के लिए) यह आपके लिए पहले से ही करते हैं।)

(इसके अलावा, मुझे वास्तव में सी # की कीवर्ड-शैली लिंक अभिव्यक्ति पसंद नहीं है क्योंकि लगभग कुछ भी करने के लिए आपको लिंक एक्सटेंशन-विधियों से निपटने की आवश्यकता है, जो कीवर्ड-शैली अभिव्यक्तियों के साथ सौंदर्यपूर्ण रूप से संघर्ष करते हैं। मैं किसी भी अच्छे के बारे में नहीं सोच सकता कीवर्ड-शैली लिंक एक्सप्रेशन इन दिनों ईमानदारी से उपयोग करने का कारण)।

मुझे लगता है कि _db आपका DbContext है।

using System.Linq;
using System.Data.Entity; // for EF6
using Microsoft.EntityFrameworkCore.Query; // for EF Core

A a = await _db.A
    .Include( a => a.B )
    .Include( a => a.B.C )
    .Include( a => a.B.C.D )
    .Where( a => a.IdA == param )
    .SingleOrDefaultAsync();

// b, c, and d can then be gotten from A:
B b = a.B;
C c = a.B.C;
D d = a.B.C?.D; // It looks like A.B and B.C are INNER JOIN while C.D is LEFT OUTER JOIN. Linq will use the correct JOIN type (INNER, LEFT, etc) based on your model configuration. You cannot tell from the query alone.

return new DTOFin() { ... };

यदि आपके पास नेविगेशन गुण सेट-अप नहीं है (और आपको करना चाहिए...) तो आप मैन्युअल रूप से Joins कर सकते हैं - लेकिन यह उल्लेखनीय रूप से अधिक स्पष्ट है क्योंकि लिंक का .Join पद्धति का कभी भी सीधे उपयोग करने का इरादा नहीं था क्योंकि आपसे इसके बजाय नेविगेशन गुणों का उपयोग करने की अपेक्षा की जाती है।

  • ध्यान दें कि चूंकि इस लिंक क्वेरी का उपयोग एंटिटी फ्रेमवर्क के साथ किया जा रहा है, इसका मतलब है कि आपकी क्वेरी एसक्यूएल में प्रतिनिधित्व योग्य होनी चाहिए ...
    • इसका मतलब है कि कुछ सीमाएं लागू होती हैं: जैसे ?. ऑपरेटर का उपयोग न करना - जो आपकी समस्या है।
    • अन्य सीमाओं में अपने स्वयं के कस्टम विधेय कार्यों का उपयोग न कर पाना शामिल है (जब तक कि वे Expression<Func<>> भी न हों) क्योंकि आप केवल C# कोड को SQL क्वेरी में नहीं डाल सकते हैं।

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

var a_b_c_d = await _db.A
    .Join( _db.B, a     => a.IdA       , b => b.IdB1, ( a    , b ) => new { a, b } )
    .Join( _db.C, a_b   => a_b.b.IdB2  , c => c.IdC1, ( a_b  , c ) => new { a_b.a, a_b.b, c } )
    .Join( _db.D, a_b_c => a_b_c.c.IdC2, d => d.IdD , ( a_b_c, d ) => new { a_b_c.a, a_b_c.b, a_b_c.c, d } )
    .Where( a_b_c_d => a_b_c_d.a.IdA == param )
    .SingleOrDefaultAsync();

A a = a_b_c_d.a;
B b = a_b_c_d.b;
C c = a_b_c_d.c;
D d = a_b_c_d.d;

return new DTOFin() { ... };
1
Dai 2 सितंबर 2021, 10:39

मुझे लगता है कि यह LINQ क्वेरी सिंटैक्स का उपयोग करके काम करेगा।

    var dto = (from a in _db.A
               join b in _db.B on a.IdA equals b.IdB1
               join c in _db.C on b.IdB2 equals c.IdC1 into cTemp
               from cT in cTemp.DefaultIfEmpty()
               join d in _db.D on c.IdC2 equals d.IdD into dTemp
               from dT in dTemp.DefaultIfEmpty()
               where a.IdA == param
               select new DTOFin 
               {
               ...
               }).FirstOrDefaultAsync();

आप cT और dT चर से c और d तालिका मान चुन सकते हैं।

0
TiginMannuel 4 सितंबर 2021, 19:04