निर्दिष्ट प्रकार के सदस्य 'तिथि' LINQ में एंटिटी अपवाद के लिए समर्थित नहीं है


105

मुझे निम्नलिखित कथनों को लागू करते समय एक अपवाद मिला।

 DateTime result;
 if (!DateTime.TryParse(rule.data, out result))
     return jobdescriptions;
 if (result < new DateTime(1754, 1, 1)) // sql can't handle dates before 1-1-1753
     return jobdescriptions;
 return jobdescriptions.Where(j => j.JobDeadline.Date == Convert.ToDateTime(rule.data).Date );

अपवाद

The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

मुझे पता है कि अपवाद का मतलब क्या है लेकिन मुझे नहीं पता कि इससे कैसे छुटकारा पाया जाए। कोई मदद?


यह ईएफ 6 और लोअर में है। ईएफ कोर सपोर्ट करता है .Date
गर्ट अर्नोल्ड

जवाबों:


102

LINQ से एंटिटीज SQL में अधिकांश .NET दिनांक विधियों (आपके द्वारा उपयोग की गई कास्टिंग सहित) का अनुवाद नहीं कर सकते हैं क्योंकि कोई समान SQL नहीं है।

समाधान LINQ कथन के बाहर दिनांक विधियों का उपयोग करना है और फिर एक मान में पास करना है। ऐसा लगता है जैसे कि Convert.ToDateTime (rule.data)। Date त्रुटि का कारण बन रहा है।

डेटटाइम प्रॉपर्टी पर कॉलिंग तिथि भी एसक्यूएल में अनुवादित नहीं की जा सकती है, इसलिए एक वर्कअराउंड की तुलना .Year .Month और .Day प्रॉपर्टीज से की जा सकती है, जिसका अनुवाद केवल पूर्णांक के रूप में किया जा सकता है।

var ruleDate = Convert.ToDateTime(rule.data).Date;
return jobdescriptions.Where(j => j.Deadline.Year == ruleDate.Year 
                       && j.Deadline.Month == ruleDate.Month 
                       && j.Deadline.Day == ruleDate.Day);

6
J => के बारे में क्या j.JobDeadline.Date?
निहारिका

1
क्या JobDeadline पर एक संपत्ति है? यह अपने आप से एक त्रुटि का कारण नहीं होना चाहिए - शायद एक नामकरण संघर्ष (लेकिन इस पर निश्चित नहीं)। यदि लाइन अभी भी त्रुटि का कारण बन रही है तो इसे डेडलाइनडेट या समान नाम दें।
जूडो

1
तिथि JobDeadline पर संपत्ति है। JobDeadline DateTime प्रकार है जिसमें से मैं Date निकालना चाहता हूँ।
नेबुला

फिर, LINQ के भीतर यह काम करने के लिए आपको जॉबडीडलाइन प्रॉपर्टी की तुलना करने की आवश्यकता होगी, जैसे j.JobDeadline> ruleDate। इसके लिए थोड़ा परीक्षण की जरूरत है लेकिन काम करने के लिए इसे बनाया जा सकता है। वैकल्पिक रूप से .Month .Day और .Year (j.Deadline.Year == ruleDate.Year && j j.Deadline.Month == ruleDate.Month && j.Deadline.Dn == ruleDate.Day) के तीन गुणों की तुलना करें। सुरुचिपूर्ण नहीं, लेकिन यह काम करता है क्योंकि ये केवल पूर्णांक हैं।
जूडो

हम्म। यह विचार काम करता है। गंदा लेकिन काम करता है। यदि आप इसे उत्तर के रूप में लिखते हैं, तो मैं इसे सही चिह्नित कर सकता हूं।
नेबुला

230

SQL में गुण का सही अनुवाद प्राप्त करने के लिए आप EntityFunctions की TruncateTime विधि का उपयोग कर सकते हैं :Date

using System.Data.Objects; // you need this namespace for EntityFunctions

// ...

DateTime ruleData = Convert.ToDateTime(rule.data).Date;
return jobdescriptions
    .Where(j => EntityFunctions.TruncateTime(j.JobDeadline) == ruleData);


अद्यतन: EntityFunctions EF6, उपयोग में पदावनत हैDbFunctions.TruncateTime


ठीक है, मैं देखा है कि ruleDataहै DateTimeप्रकार और j.JobDeadlinetruncatedtime है। ठीक नहीं लगता। अपवाद नहीं मिला, लेकिन अपेक्षित परिणाम भी नहीं मिला।
नेबुला

@ इनल: यह सभी रिकॉर्ड लौटाता JobDeadlineहै, जहां एक ही तारीख होती है rule.data, चाहे दिन का समय कैसा भी हो । क्या यह नहीं है कि आप प्रश्न में अपनी क्वेरी के साथ क्या हासिल करना चाहते हैं? यह सही क्यों नहीं लगता?
सुलामा

1
+1 और मैं ऊपर से सहमत हैं, निश्चित रूप से 99% कार्यान्वयन के लिए एक बेहतर उत्तर है
jim टोलन

26
ध्यान दें कि EntityFunctionsEF6 में पदावनत किया गया है, अब आपको उपयोग करना चाहिए DbFunctions
जूलियन एन

2
DFFunctions के लिए N नाम स्थान> EF6 है System.Data.Entity: msdn.microsoft.com/en-us/library/Dn220142(v=VS.113).aspx
GraehamF


9

Ef6 में "EntityFunctions.TruncateTime" या "DbFunctions.TruncateTime" काम कर रहा है, लेकिन बिग डेटा में कुछ प्रदर्शन समस्या है।

मुझे लगता है कि इस तरह से अभिनय करना सबसे अच्छा तरीका है:

DateTime ruleDate = Convert.ToDateTime(rule.data);

DateTime  startDate = SearchDate.Date;

DateTime  endDate = SearchDate.Date.AddDay(1);

return jobdescriptions.Where(j.Deadline >= startDate 
                       && j.Deadline < endDate );

यह तारीख के कुछ हिस्सों का उपयोग करने से बेहतर है। क्योंकि क्वेरी को बड़े डेटा में तेजी से चलाया जाता है।


इस उत्तर के लिए +1। EntityFunctions.TruncateTime(बाद में बदल दिया गया DbFunctions.TruncateTime) एसक्यूएल में परिवर्तित करके लागू किया जाता है जहां डेटाइम को स्ट्रिंग में परिवर्तित किया जाता है और जिसे काट दिया जाता है। यह क्वेरी को संसाधित रिकॉर्ड की संख्या के अनुपात में काफी धीमी गति से चलाता है।
यूरिग

3

शामिल करने की आवश्यकता है using System.Data.Entity;। साथ ही अच्छी तरह से काम करता हैProjectTo<>

var ruleDate = rule.data.Date;
return jobdescriptions.Where(j => DbFunctions.TruncateTime(j.Deadline) == ruleDate);


1

इसका क्या मतलब है कि LINQ to SQL को पता नहीं है कि Dateसंपत्ति को SQL अभिव्यक्ति में कैसे बदलना है । ऐसा इसलिए है क्योंकि संरचना की Dateसंपत्ति का DateTimeएसक्यूएल में कोई एनालॉग नहीं है।


1

इसने मेरे लिए काम किया।

DateTime dt = DateTime.Now.Date;
var ord = db.Orders.Where
      (p => p.UserID == User && p.ValidityExpiry <= dt);

स्रोत: Asp.net फ़ोरम


0

मुझे भी यही समस्या है लेकिन मैं डेटटाइम-रेंज के साथ काम करता हूं। मेरा समाधान शुरू होने के समय (किसी भी तारीख को) के साथ 00:00:00 और अंत-समय से 23:59:59 तक हेरफेर करना है, इसलिए मुझे अपनी डेटटाइम को डेट में कनवर्ट नहीं करना चाहिए, बल्कि यह डेटटाइम रहता है।

अगर आपके पास सिर्फ एक डेटटाइम है, तो आप स्टार्ट-टाइम (किसी भी तारीख के साथ) को 00:00:00 बजे और एंड-टाइम को 23:59:59 पर सेट कर सकते हैं।

var from = this.setStartTime(yourDateTime);
var to = this.setEndTime(yourDateTime);

yourFilter = yourFilter.And(f => f.YourDateTime.Value >= from && f.YourDateTime.Value <= to);

आप इसे डेटटाइम-रेंज के साथ भी कर सकते हैं:

var from = this.setStartTime(yourStartDateTime);
var to = this.setEndTime(yourEndDateTime);

yourFilter = yourFilter.And(f => f.YourDateTime.Value >= from && f.YourDateTime.Value <= to);

0

आप Enum प्राप्त कर सकते हैं जैसे:

DateTime todayDate = DateTime.Now.Date; var check = db.tableName.AsEnumerable().Select(x => new
        {
            Date = x.TodayDate.Date
        }).Where(x => x.Date == todayDate).FirstOrDefault();

दिनांक फ़िल्टर लागू करने के लिए यह तालिका की पूरी सामग्री को पहले से ही प्रभावी रूप से मान रहा है ... ऐसा लगता है कि संभवतः एक बहुत बुरा विचार है!
जेवियर रापोपोर्ट 14

0

जैसा कि यहां कई लोगों ने बताया है, TruncateTime फ़ंक्शन का उपयोग धीमा है।

सबसे आसान विकल्प यदि आप ईएफ कोर का उपयोग कर सकते हैं। यह यह कर सकता है। यदि आप ट्रंकट के लिए एक बेहतर विकल्प नहीं हो सकते हैं, तो क्वेरिड फ़ील्ड को बिल्कुल भी न बदलें, लेकिन सीमा को संशोधित करें। यदि आप 'टाइप' क्वेरी के बीच एक सामान्य 'कर रहे हैं जहां निचले और ऊपरी सीमाएं वैकल्पिक हैं, तो निम्न चाल चलेगी।

    public Expression<Func<PurchaseOrder, bool>> GetDateFilter(DateTime? StartDate, DateTime? EndDate)
    {
        var dtMinDate = (StartDate ?? SqlDateTime.MinValue.Value).Date;
        var dtMaxDate = (EndDate == null || EndDate.Value == SqlDateTime.MaxValue.Value) ? SqlDateTime.MaxValue.Value : EndDate.Value.Date.AddDays(1);
        return x => x.PoDate != null && x.PoDate.Value >= dtMinDate && x.PoDate.Value < dtMaxDate;
    }

मूल रूप से, PoDate को केवल दिनांक भाग में वापस करने के बजाय, हम ऊपरी क्वेरी बाध्य और उपयोगकर्ता <के बजाय <= बढ़ाते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.