2010-01-27 13 views
12

के लिए एक पुन: प्रयोज्य विधेय बनाना मेरी LINQ में मैं विभिन्न तालिकाओं जो मूल रूप से संस्करण का समर्थन करने के लिए एक ही इंटरफ़ेस का समर्थन जो वर्गों के लिए मैप किया जाता है है, यानीएसक्यूएल सेटअप करने के लिए EntitySet <T>, IQueryable <T> और IEnumerable <T>

public interface IValid 
{ 
    int? validTo { get; } 
    int validFrom { get; } 
} 

LINQ एसक्यूएल वर्गों के लिए इस तरह इस इंटरफेस से निकाले जाते हैं:

public partial class representationRevision : IValid 
{ 
} 

अब मैं एक सूखी (खुद को दोहराना नहीं) को छानने EntitySet<T> के रास्ते,परिभाषित करना चाहते हैंऔर IQueryable<T> ताकि परिणामस्वरूप सूचियां एक विशिष्ट संशोधन के लिए मान्य हों। मैंने यह करने की कोशिश की है:

public static class ExtensionMethods 
{ 

    public static IQueryable<T> ValidFor<T>(this IQueryable<T> v, int? revision) 
     where T : IValid 
    { 
     return v.Where(cr => ((cr.validFrom <= revision) && 
      ((cr.validTo == null) || (cr.validTo > revision))) 
      || ((revision == null) && (cr.validTo == null)) 
      ); 
    } 
} 

लेकिन इससे EntitySet<T> पर समस्याएं आती हैं। मैंने EntitySet के लिए एक विशेष कार्यान्वयन जोड़ा जो पहले AsQueryable() को कॉल करता है, लेकिन यह अपवाद फेंकता है। जब .Where<contentRevision>(IsValidFor(revision)) के साथ प्रयोग किया

public static Expression<Func<contentRevision, bool>> IsValidFor(int? revision) 
    { 
     return ((cr) => ((cr.validFrom <= revision) && 
      ((cr.validTo == null) || (cr.validTo > revision))) 
      || ((revision == null) && (cr.validTo == null))); 
    } 

ऐसा त्रुटियों देता है::

त्रुटि 5 'System.Data.Linq.EntitySet' नहीं है अडिग मैं एक विधेय तो मैं Where(predicate) दृष्टिकोण इस्तेमाल कर सकते हैं बनाने की कोशिश की 'कहाँ' के लिए एक परिभाषा और सबसे अच्छा विस्तार विधि अधिभार
'System.Linq.Enumerable.Where (System.Collections.Generic.IEnumerable, System.Func)' शामिल कुछ अमान्य तर्क

है

ध्यान दें कि यह भी IValid इंटरफ़ेस का उपयोग किए बिना है ... मैं इस विषय पर सभी प्रकार की विविधताओं (जैसे int पैरामीटर जोड़ने की कोशिश कर रहा हूं) लेकिन वे सभी असफल रूप से विफल होने लगते हैं। मुझे सही दिशा में लाने के लिए कोई संकेतक?

+0

ऊपर अपने स्थिर अभिव्यक्ति फ़ंक्शन में, पहला प्रकार पैरामीटर 'contentRevision' है, क्या यह एक टाइपो है? मैं उम्मीद करता हूं कि यह 'IValid' हो। इसके अलावा आप नीचे दी गई त्रुटि को 3 प्रकार के पैरामीटर के साथ एक अनुमान में गुजरने का परिणाम प्रतीत होता है। क्या होता है यदि आप भविष्यवाणी के रूप में भविष्यवाणी करते हैं ('अभिव्यक्ति > ')? मैंने इसका बहुत उपयोग किया है और यह ठीक काम करता है, मैं आपकी पोस्ट से नहीं समझ सकता कि आपका कोड संकलित क्यों नहीं होगा। –

+0

यह कोड के नीचे टिप्पणी में है "ध्यान दें कि यह भी IValid इंटरफ़ेस का उपयोग किए बिना है"।असल में मैंने इसे पहले आईवालिड का उपयोग किए बिना काम करने की कोशिश की, लेकिन इस समय व्यवहार में कोई अंतर नहीं है। मुझे लगता है कि यह एंटीटीसेट के साथ विशेष रूप से कुछ करने के लिए है: यदि मैं तालिका में शामिल होने के लिए अपना कोड दोबारा लिखता हूं तो सब ठीक काम करने लगता है। –

उत्तर

4

EntitySet<T> के बारे में सुनिश्चित नहीं है तो IQueryable<T> और IEnumerable<T> पर ध्यान केंद्रित करेगा।

LINQ प्रदाता अभिव्यक्ति पेड़ों का मूल्यांकन करने की अनुमति देने के लिए IQueryable<T> इसके अभिव्यक्ति तर्कों के लिए उपयोग करता है, किसी को अंतर्निहित इंटरफ़ेस संरक्षित करने की आवश्यकता है। अन्यथा IEnumerable<T> की अवधि में सबकुछ करें (यानी यदि आप पूरे डेटासेट को स्थानीय मेमोरी में खींचने के लिए ठीक हैं और फिर डेटाबेस में बजाए इसे वहां संसाधित करते हैं, तो केवल LINQ से ऑब्जेक्ट्स का उपयोग करें)।

अन्य विकल्प AsQueryable विस्तार विधि (Queryable वर्ग का हिस्सा) जो एक IQueryable<T> करने के लिए एक IEnumerable<T> धर्मान्तरित, और फिर आप कोड के बाकी साझा कर सकते हैं।

IQueryable<T> SomeSharedQuery(this IQueryable<T> source) { 
    return source.(LINQ query operators...); 
} 
IQueryable<T> SomeSharedQuery(this IEnumerable<T> source) { 
    return source.AsQueryable().SomeSharedQuery(); 
} 

तो आपके पास एडाप्टर विधि के साथ साझा कोड है।

+1

यह शानदार ढंग से काम करता है, लेकिन एंटीटीसेट के लिए नहीं। AsQueryable() में SQL (अजीब रूप से पर्याप्त) का अनुवाद नहीं है। –

+0

@Matthijs: Bawed डॉक्स 'पर EntitySet ' लागू करता है 'IEnumerable ' ताकि आप एक मैच मिल जाएगा। 'देखते हुए EntitySet ' कोई मौजूदा क्वेरी आप उस पर एक 'IQueryable ' कार्यान्वयन से कुछ भी हासिल नहीं करते हैं के कुछ हिस्सों के बारे में आलसी लोड हो रहा है ... यदि आप db संघ भर में काम करना चाहते हैं शामिल है कि मूल में क्वेरी। – Richard

+0

'EntitySet ' के लिए यह किस तरह से काम नहीं करता है? – svick

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