2015-07-14 19 views
9

मैं इसLINQ विस्तार विधि का समर्थन नहीं करता है? मैं इस क्वेरी में सब कुछ विस्तार विधि से उपयोग करते हैं

public static IQueryable<T> CurrentVersion(this IQueryable<T> queryable, DateTime date) 
    { 
     return queryable.Where(p => p.CreationDate>date); 
    } 

    public static IEnumerable<T> CurrentVersion(this IEnumerable<T> queryable, DateTime date) 
    { 
     return queryable.Where(p => p.CreationDate>date); 
    } 

मेरे मॉडल की तरह दो विस्तार तरीकों

public class Group { 
    .. 
    ICollection<GroupMembers> GroupMembers { get; set; } 
} 

है ठीक है

var q = Db.Groups.CurrentVersion(); 
var result = q.ToList(); 

लेकिन जब मैं इसका इस्तेमाल बह क्वेरी में मैं कोई त्रुटि मिलती है

var q = Db.Groups.SelectMany(p => p.GroupMembers.AsQueryable().CurrentVersion(date)); 

OR 

var q = Db.Groups.SelectMany(p => p.GroupMembers.AsEnumerable().CurrentVersion(date)); 

var result = q.ToList(); // Here I get error 

त्रुटि:

LINQ to Entities does not recognize the method 'System.Linq.IQueryable 1[..](System.Linq.IQueryable 1[..., System.DateTime)' method, and this method cannot be translated into a store expression.

अब मैं दो प्रश्न हैं:

  1. मैं यह त्रुटि googled और stackoverflow में मेरे सवाल के रूप में ही कई समस्याओं पाया। सभी उत्तरों थे "इकाइयों के लिए लिंक इस विस्तार विधि को SQL क्वेरी में परिवर्तित नहीं कर सकता"। अब मैं अगर किसी को मेरी मदद को पता है, क्यों मेरी पहली क्वेरी किसी भी त्रुटि उठाना नहीं है आभारी होंगे?

  2. मुझे अपने एक्सटेंशन विधि है जो Linq करने वाली संस्थाओं द्वारा मान्यता प्राप्त किया जा सकता है कैसे बदल सकता हूँ?

उत्तर

6

लिंक क्वेरी को एसक्यूएल में अनुवाद करने की आवश्यकता है। आप अपने CurrentVersion विस्तार इस तरह इनलाइन कहा जाता है जब:

Db.Groups.CurrentVersion(); 

तो एफई सिर्फ CurrentVersion विधि invokes, IQueryable वस्तु जिसके परिणामस्वरूप हो जाता है और क्वेरी करने के लिए में बदल देती है। दूसरी ओर उस क्वेरी के मामले में:

var q = Db.Groups.SelectMany(p => p.GroupMembers.AsQueryable().CurrentVersion(date)); 

SelectMany में आंतरिक अभिव्यक्ति को कोड में कभी भी शामिल नहीं किया जा सकता है! इसका अनुवाद एसक्यूएल में किया जाना है। तो यह अभिव्यक्ति वस्तु के रूप में व्यवहार किया जाता है और यह तब पार्स किया गया है, लेकिन आपके मामले में यह अभिव्यक्ति आह्वान के रूप में आप विधि लागू कर रहे हैं, लेकिन यह स्पष्ट कारण से SQL में अनुवाद नहीं किया जा सकता है। तो SelectMany लैम्ब्डा parameer आप किसी भी विधि को लागू नहीं किया जा सकता के भीतर से, तुम वहाँ उचित अभिव्यक्ति प्रदान करने के लिए है। CurrentVersion विधि द्वारा प्रदान की जाने वाली सबसे मूल्यवान चीज़ अभिव्यक्ति फ़िल्टर कर रही है। इस तरह से अपनी विधि बदलें:

public static Expression<T, bool> CurrentVersion(DateTime date) 
{ 
    return p => p.CreationDate > date; 
} 

एक इस तरह इसका इस्तेमाल:

var q = Db.Groups.Where(ExpressionsHelper.CurrentVersion(date)); 
... 
Expression<T, bool> filterExpression = ExpressionsHelper.CurrentVersion(date); 
Db.Groups.SelectMany(p => p.GroupMembers.AsQueryable().Where(filterExpression)); 

आप whish आप stil नई विधि के साथ अपने विस्तार विधि साझा करने को छानने तर्क हो सकता है, तो:

public static IQueryable<T> CurrentVersion(this IQueryable<T> queryable, DateTime date) 
{ 
    return queryable.Where(ExpressionsHelper.CurrentVersion(date)); 
} 
+0

मुझे लगता है कि आपका एक्सटेंशन मेरी विस्तार विधि से अलग नहीं है क्योंकि पूछताछ योग्य है। (ExpressionsHelper.CurrentVersion (date)) क्वेरी करने योग्य के साथ समान है। जहां (p => p.CreationDate> date); –

+0

वास्तव में पूछताछ योग्य। कहाँ (अभिव्यक्तिहेल्पर। कंटेंटवर्सन (दिनांक)) को क्वेरी करने योग्य के रूप में काम करना चाहिए। जहां (पी => पी। क्रिएशनडेट> दिनांक); लेकिन यह लक्ष्य था, है ना? मैंने आपकी विधि बदल दी है ताकि आपके फ़िल्टरिंग तर्क का पुन: उपयोग किया जा सके, जैसा आपने चाहें। तो अंतर यह होना चाहिए कि मेरे द्वारा प्रस्तावित विधि काम कर रही है और ईएफ इसे क्वेरी करने के लिए पार्स कर सकता है। – mr100

+0

लेकिन CurrentVersion एक्सटेंशन विधि का मेरा संस्करण आपके नेस्टेड क्वेरी पर लागू नहीं किया जा सकता है! आप इसे केवल डीबी ग्रुप जैसे सरल प्रश्नों के साथ उपयोग कर सकते हैं।वर्तमान संस्करण(); जटिल लोगों के लिए आपको Db.Groups.SelectMany (p => p.GroupMembers.AsQueryable() का उपयोग करने की आवश्यकता है। (ExpressionsHelper.CurrentVersion (दिनांक)); एक्सटेंशन विधि केवल नमूना के रूप में प्रस्तुत की जाती है - यदि आप इसे चाहते हैं, तो आप इसे कोड डुप्लिकेशन के बिना प्राप्त कर सकते हैं। – mr100

संबंधित मुद्दे