2009-09-19 11 views
33

के बीच LINQ निम्न कार्य IENumerable प्रकारों के साथ ठीक काम करता है, लेकिन क्या SQL सर्वर के विरुद्ध IQueryable प्रकारों के साथ काम करने जैसा कोई तरीका है?ऑपरेटर

class Program 
{ 
    static void Main(string[] args) 
    { 
     var items = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, }; 

     foreach (var item in items.Where(i => i.Between(2, 6))) 
      Console.WriteLine(item); 
    } 
} 

static class Ext 
{ 
    public static bool Between<T>(this T source, T low, T high) where T : IComparable 
    { 
     return source.CompareTo(low) >= 0 && source.CompareTo(high) <= 0; 
    } 
} 

उत्तर

44

आप एक where खंड यह सिर्फ एसक्यूएल करने के लिए LINQ के साथ बॉक्स से बाहर काम कर सकते हैं, यदि आप एक उचित अभिव्यक्ति का निर्माण कर सकते के रूप में यह व्यक्त करते हैं।

अभिव्यक्ति पेड़ों के संदर्भ में ऐसा करने का एक बेहतर तरीका हो सकता है - मार्क ग्रेवेल इसे बेहतर बनाने में सक्षम हो सकता है - लेकिन यह एक कोशिश के लायक है।

static class Ext 
{ 
    public static IQueryable<TSource> Between<TSource, TKey> 
     (this IQueryable<TSource> source, 
     Expression<Func<TSource, TKey>> keySelector, 
     TKey low, TKey high) where TKey : IComparable<TKey> 
    { 
     Expression key = Expression.Invoke(keySelector, 
      keySelector.Parameters.ToArray()); 
     Expression lowerBound = Expression.GreaterThanOrEqual 
      (key, Expression.Constant(low)); 
     Expression upperBound = Expression.LessThanOrEqual 
      (key, Expression.Constant(high)); 
     Expression and = Expression.AndAlso(lowerBound, upperBound); 
     Expression<Func<TSource, bool>> lambda = 
      Expression.Lambda<Func<TSource, bool>>(and, keySelector.Parameters); 
     return source.Where(lambda); 
    } 
} 

यह शायद हालांकि प्रकार शामिल पर निर्भर करेगा - विशेष रूप से, मैं नहीं बल्कि IComparable<T> से तुलना ऑपरेटरों का उपयोग किया। मुझे संदेह है कि एसक्यूएल में इसका सही अनुवाद होने की संभावना है, लेकिन यदि आप चाहें तो CompareTo विधि का उपयोग करने के लिए इसे बदल सकते हैं।

इस तरह यह आह्वान:

var query = db.People.Between(person => person.Age, 18, 21); 
+0

अच्छा लगा। इसने मुझे लिंक अभिव्यक्तियों को थोड़ा और समझ लिया। – Dykam

+0

जॉन, क्षमा करें मैंने इसे स्वीकार नहीं किया है। कुछ दिनों के लिए मौसम के नीचे किया गया। प्रश्न: आप IComparable के बजाय तुलना ऑपरेटर का उपयोग करने के बारे में लिखते हैं। वो कैसा लगता है? इस तरह का कोई भी आईन्यूमेरेबल जैसा दिखता है? मुझे इसके साथ खेलना है और आज ऐसा करने की उम्मीद है। बहुत धन्यवाद! – andleer

+0

'IComparable 'का उपयोग करके आपको तुलनात्मक दो बार तुलना करने के लिए अभिव्यक्ति पेड़ की आवश्यकता होगी। सभी काम करने योग्य, लेकिन दर्द का थोड़ा सा। सुनिश्चित नहीं है कि आप किस बारे में क्या मतलब रखते हैं "यह कोई भी 'IENumerable '' जैसा दिखता है? - क्या आप विस्तार से समझा सकते हैं? –

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