LINQ To Entities अंतिम विधि को नहीं पहचानता है। वास्तव में?


144

इस प्रश्न में:

public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
    var context = DataContext.GetDataContext();
    return context.ServerOnlineCharacters
        .OrderBy(p => p.ServerStatus.ServerDateTime)
        .GroupBy(p => p.RawName)
        .Select(p => p.Last());
}

मुझे इसे काम करने के लिए इसे स्विच करना पड़ा

public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
    var context = DataContext.GetDataContext();
    return context.ServerOnlineCharacters
        .OrderByDescending(p => p.ServerStatus.ServerDateTime)
        .GroupBy(p => p.RawName)
        .Select(p => p.FirstOrDefault());
}

मैं p.First()पहली क्वेरी को मिरर करने के लिए भी उपयोग नहीं कर सका ।

ऐसी मूल ORM प्रणाली में ऐसी बुनियादी सीमाएँ क्यों हैं?


अपनी IEnumrable ऑब्जेक्ट को एक नए वेरिएबल में स्टोर करें, फिर वेरिएबल लौटाएँ ()। यह काम करेगा।
अली.राशिदी

जवाबों:


220

यह सीमा इस तथ्य तक कम हो जाती है कि अंततः उस क्वेरी को SQL में ट्रांसलेट करना पड़ता है और SQL में एक SELECT TOP(T-SQL में) होता है, लेकिन ऐसा नहीं SELECT BOTTOM(कोई ऐसी बात नहीं)।

हालांकि, इसके चारों ओर एक आसान तरीका है, बस नीचे उतरने का आदेश दें और फिर एक करें First(), जो आपने किया है।

EDIT:SELECT TOP 1 ओरेकल पर अन्य प्रदाताओं के संभवतः अलग-अलग कार्यान्वयन होंगे , यह संभवतः कुछ और पसंद होगाWHERE ROWNUM = 1

संपादित करें:

एक और कम कुशल विकल्प - मैं यह अनुशंसा नहीं करता! - .ToList()पहले अपने डेटा पर कॉल करना है .Last(), जो उस बिंदु तक बनाए गए LINQ To Entities Expression को तुरंत निष्पादित करेगा, और फिर आपका .Last () काम करेगा, क्योंकि उस बिंदु पर .Last()एक के संदर्भ में प्रभावी रूप से निष्पादित किया जाता है। LINQ ऑब्जेक्ट्स के बजाय अभिव्यक्ति। (और जैसा कि आपने बताया, यह CPU अभिलेखों के हजारों और बेकार भारों को वापस ला सकता है जो कभी भी उपयोग नहीं किए जाएंगे)

फिर, मैं इसे दूसरा करने की सलाह नहीं दूंगा, लेकिन यह LINQ अभिव्यक्ति के निष्पादन के समय और उसके बीच के अंतर को स्पष्ट करने में मदद करता है।


और LINQ To SQL इस परिदृश्य से कैसे निपटता है?
bevacqua

@ हाँ, मुझे पता है कि मैं टॉलिस्ट को कॉल कर सकता हूं, लेकिन मैं डेटाबेस से हजारों रिकॉर्ड्स को सिर्फ पांच रिकॉर्ड तक फ़िल्टर करने के लिए पुनर्प्राप्त नहीं
करूंगा

2
यदि आपको पता है कि आपकी क्वेरी छोटे परिणाम देने जा रही ToListहै , तो कॉलिंग उतना बुरा नहीं है।
जस्टिन स्काइल्स 19'13

35

इसके बजाय Last(), यह कोशिश करें:

model.OrderByDescending(o => o.Id).FirstOrDefault();

14

Last()एक Linq चयनकर्ता द्वारा बदलेंOrderByDescending(x => x.ID).Take(1).Single()

कुछ ऐसा होगा जो काम करेगा अगर आप इसे Linq में करते हैं:

public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
    var context = DataContext.GetDataContext();
    return context.ServerOnlineCharacters.OrderBy(p => p.ServerStatus.ServerDateTime).GroupBy(p => p.RawName).Select(p => p.OrderByDescending(x => x.Id).Take(1).Single());
}

1
क्या इसका उपयोग करने का कोई कारण है। टेक (1)। सिंगल () के बजाय .FirstOrDefault ()?
Tot जम

2
@TotZam वैध प्रतिस्थापन होगा। उस स्थिति में। चूंकि सिंगल () एक अपवाद फेंकता है यदि आइटम की गिनती ठीक 1 नहीं है।
मेमार्क

0

फिर भी एक और तरीका आर्डरबायस्केंडिंग के बिना अंतिम तत्व प्राप्त करना और सभी संस्थाओं को लोड करना है:

dbSet
    .Where(f => f.Id == dbSet.Max(f2 => f2.Id))
    .FirstOrDefault();

0

ऐसा इसलिए है क्योंकि LINQ से एंटिटीज़ (और सामान्य रूप से डेटाबेस) सभी LINQ तरीकों का समर्थन नहीं करते हैं (विवरण के लिए यहां देखें: http://msdn.microsoft.com/en-us/library/bb738550.aspx )

यहां आपको जो कुछ भी चाहिए वह आपके डेटा को इस तरह से ऑर्डर करना है कि "अंतिम" रिकॉर्ड "पहले" हो जाए और फिर आप फ़र्स्टऑर्डडेफ़ल का उपयोग कर सकें। ध्यान दें कि डेटाबेस में आमतौर पर "पहले" और "अंतिम" जैसी अवधारणाएं नहीं होती हैं, यह तालिका में सबसे हाल ही में डाला गया रिकॉर्ड "अंतिम" जैसा नहीं होगा।

यह तरीका आपकी समस्या को हल कर सकता है

db.databaseTable.OrderByDescending(obj => obj.Id).FirstOrDefault();

-2

AsEnumerable()मेरे लिए काम का चयन करने से पहले एकल फ़ंक्शन जोड़ना ।
उदाहरण:

return context.ServerOnlineCharacters
    .OrderByDescending(p => p.ServerStatus.ServerDateTime)
    .GroupBy(p => p.RawName).AsEnumerable()
    .Select(p => p.FirstOrDefault());

रेफरी: https://www.codeproject.com/Questions/1005274/LINQ-to-Entities-does-not-recognize-the-method-Sys


यह सलाह दी जाती है कि आपके उत्तर के लिंक से कार्य कोड को शामिल किया जाए। लिंक-केवल उत्तर नकारात्मक ध्यान आकर्षित करेंगे। कृपया उस कोड को जोड़कर एक पूर्ण उत्तर प्रदान करें जो आपने समस्या को हल करने में मदद के लिए पाया है। यह भविष्य में 404 त्रुटियों के कारण काम न करने वाले लिंक की समस्या को हल करता है।
स्टडोकव्हो

1
मेरे जवाब के लिए उदाहरण जोड़ा
आर्टेम लेविटिन

इस उत्तर के लिए नीचे की ओर यह है कि यह "AsEnumerable" सर्वर साइड से पहले सभी परिणाम लाएगा और फिर पहले वाले को चुनें। यह बहुत अवांछनीय हो सकता है। (मेरे पास इस तरह की स्थिति थी जहां 20k + रिकॉर्ड सर्वर-साइड लाए जाने के कारण परिणाम 20+ सेकंड ले रहे थे, एक बार मैंने इसे DB साइड वापस ले लिया, परिणाम एक सेकंड से भी कम समय में वापस आ गए)
TChadwick
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.