Linq से EntityFramework DateTime तक


108

अपने आवेदन में मैं एंटिटी फ्रेमवर्क का उपयोग कर रहा हूं।

मेरी टेबल

-Article
-period
-startDate

मुझे उस मैच => के रिकॉर्ड चाहिए DateTime.Now > startDate and (startDate + period) > DateTime.Now

मैंने इस कोड की कोशिश की लेकिन अब यह काम कर रहा है

Context.Article
    .Where(p => p.StartDate < DateTime.Now)
    .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now)

जब मैं अपना कोड चलाता हूं तो निम्न अपवाद होते हैं

LINQ to Entities विधि 'System.DateTime AddDays (Double)' विधि को नहीं पहचानता है, और इस पद्धति का स्टोर अभिव्यक्ति में अनुवाद नहीं किया जा सकता है।


किस प्रकार का है period? AddDaysअगर यह एक गलत कार्य है double
क्रेग स्टंट्ज़ 15

जवाबों:


201

LINQ से एंटिटी फ्रेमवर्क का उपयोग करते समय, आपके क्लॉज़ जहाँ SQL में अनुवादित हो जाते हैं। आपको वह त्रुटि मिल रही है क्योंकि SQL के लिए कोई अनुवाद नहीं है DateTime.Add()जिसके लिए समझ में आता है।

एक त्वरित कार्य-आस-पास के परिणाम को पढ़ने के लिए होगा जहां पहले कथन स्मृति में है और फिर फ़िल्टरिंग समाप्त करने के लिए ऑब्जेक्ट्स में LINQ का उपयोग करें:

Context.Article.Where(p => p.StartDate < DateTime.Now)
               .ToList()
               .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now);

यदि आप .NET 4.0 का उपयोग कर रहे हैं, तो आप EntityFunctions.AddDays विधि भी आज़मा सकते हैं:

Context.Article.Where(p => p.StartDate < DateTime.Now)
               .Where(p => EntityFunctions.AddDays(p.StartDate, p.Period)
                   > DateTime.Now);

नोट: EF 6अब इसमें है System.Data.Entity.DbFunctions.AddDays


42
यह एक खतरनाक काम है, अगर टोलिस्ट () भारी मात्रा में डेटा लौटाता है, तो क्या होता है?
स्टेफन पी।

7
EntityFunctions के लिए धन्यवाद। विशेष टिप मैं EF .net 4.0 का उपयोग कर रहा हूं, लेकिन मुझे EntityFunctions के बारे में नहीं पता था, इस पर गौर करेंगे।
स्टीफन पी।

2
@SaeedAlg - पहले उदाहरण में वस्तुओं को स्मृति में पढ़ना आवश्यक है। दूसरे उदाहरण में मैंने मूल प्रारूप से मेल खाने के लिए दो व्हेयर क्लाज रखे। यहां तक ​​कि अगर आप दोनों को एक एकल खंड में संपीड़ित करते हैं, तो एंटिटी फ्रेमवर्क पहचान SQL उत्पन्न करता है, इसलिए यह वास्तव में पठनीयता का मामला है।
जस्टिन नीस्नर

2
@ जस्टिन निस्नेर बहुत बहुत धन्यवाद, मैं यह करने की कोशिश कर रहा हूं कि चार घंटे के लिए, आप सेकंड में मेरे जीवन को फिर से धन्यवाद देते हैं
युकेल

2
EF के साथ "क्विक" वर्क-अराउंड देते समय, हम सभी को ToList और ToArray विधियों के उपयोग से बचना चाहिए। यह पहले की तारीख की गणना करने और उस मूल्य की तुलना करने के लिए उतनी ही जल्दी है, और यह एक ईएफ क्वेरी में मेमोरी में इसके परिणामों को तत्काल किए बिना काम करता है।
इसहाक लेलोपिस

92

मुझे लगता है कि यह वही है जो आखिरी उत्तर देने की कोशिश कर रहा था, लेकिन p.startdat (कुछ जिसे sql स्टेटमेंट में परिवर्तित नहीं किया जा सकता है) में जोड़ने की कोशिश करने के बजाय ऐसा कुछ क्यों न करें जो sql के बराबर हो सकता है:

var baselineDate = DateTime.Now.AddHours(-24);

something.Where(p => p.startdate >= baselineDate)

2
@ एड्रियन कैर - यह उपयोग के मामले के लिए बेहतर हो सकता है लेकिन EntityFunctionsसमाधान के रूप में कई के लिए नहीं । यहां, दूसरे ऑपरेंड को क्वेरी में किसी अन्य इकाई से पुनर्प्राप्त नहीं किया जाता है और क्वेरी करने से पहले गणना की जा सकती है। यदि दोनों ऑपरेंड db में पाए जाते हैं, तो EntityFunctionsसमाधान अभी भी उपयुक्त होगा जबकि इस प्रतिक्रिया का समाधान अब काम नहीं करेगा।
Frédéric

यह उत्तर के रूप में चिह्नित समाधान से बेहतर समाधान है। जस्टिन / चिह्नित जवाब से प्रतिक्रिया डेटाबेस से अनावश्यक परिणाम लौटाएगी। यह समाधान वास्तव में एसक्यूएल में तारीख भेजता है जहां डेटा को फिल्टर करने के लिए एसक्यूएल का उपयोग करता है, जो बहुत अधिक प्रदर्शन करता है।
पॉल

3

DateTime.Now से 2 दिन घटाने के बारे में:

Context.Article
.Where(p => p.StartDate < DateTime.Now)
.Where(p => p.StartDate > DateTime.Now.Subtract(new TimeSpan(2, 0, 0, 0)))

ईमानदार होने के लिए, मुझे यकीन नहीं है कि आप क्या हासिल करने की कोशिश कर रहे हैं, लेकिन यह काम कर सकता है


लेख StartDate पर दिखाए जाने लगेंगे और x (अवधि) दिनों के बाद समाप्त होंगे। यही मैं करने की कोशिश कर रहा हूं। जस्टिन नीसनर के दूसरे समाधान ने बहुत अच्छी तरह से काम किया जो मैं देखना चाहता हूं
युकेल

3

यदि आपको आवश्यकता है कि आपकी अभिव्यक्ति SQL में अनुवादित हो जाए तो आप उपयोग करने का प्रयास कर सकते हैं

System.Data.Entity.Core.Objects.AddDays विधि।

वास्तव में अप्रचलित चिह्नित है लेकिन यह काम करता है। यह System.Data.Entity.DbFunctions.AddDays द्वारा प्रतिस्थापित किया जाना चाहिए, लेकिन मैं इसे नहीं ढूँढ सकता ...


यह 4 साल से पहले स्वीकार किए गए उत्तर से ज्यादा कुछ नहीं जोड़ता है!
एंड्रयू हैरिस

@AndrewHarris भी मेरा जवाब 4 साल पहले का जवाब है। उत्तर के पहले संस्करण में कहां से पहले एक ToList (=> डेटा सामग्रीकरण) थे (उत्तर की पहली टिप्पणी देखें)।
बुबी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.