2013-03-12 7 views
7

के लिए अभिव्यक्ति पेड़ के साथ कोई भी मैं System.Linq.Expressions.Expression क्लास का उपयोग कर गतिशील रूप से एक SQL "WHERE" खंड बना रहा हूं। यह सरल खंडों के लिए अच्छा काम करता है, उदा।IQueryable बनाएँ। LINQ क्वेरी

var equalTarget = Expression.Constant(phaseCode, typeof(int?)); 
var phaseEquals = Expression.Equal(Expression.PropertyOrField(projParam, "PhaseCode"), equalTarget); 

हालांकि, अब मैं एक अभिव्यक्ति है कि रिकॉर्ड रिटर्न होगा अगर एक परियोजना एक विशेष समूह के लिए सौंपा गया है का निर्माण करने की कोशिश कर रहा हूँ: "PhaseCode = एक्स" खंड जोड़ने के लिए, मैं निम्न कार्य करें। परियोजना और समूह में कई से अधिक रिश्ते हैं। अभिव्यक्ति के पेड़ के बिना, मैं इसे करते हैं इस प्रकार हैं:

db.Projects.Where(p => .... && p.GroupsAssigned.Any(g => g.ID == groupId)) 

हालांकि, मैं अभिव्यक्ति वर्ग के साथ है कि व्यक्त करने के लिए एक रास्ता खोज नहीं कर पा रहे। वहाँ वास्तव में दो बातें मैं समझ नहीं कर सकते हैं:

  • ()

टेबल

  • के बीच संबंधों x.Any कैसे करना है किसी भी मदद की बहुत सराहना कर रहा है कैसे पार करने के लिए।

  • उत्तर

    10

    Enumerable.Any या Queryable.Any जैसे एक्सटेंशन विधि को कॉल करना, अनुक्रम पर एक स्थैतिक विधि कॉल और WHERE खंड के लिए बनाई गई लैम्ब्डा अभिव्यक्ति है। आप Expression.Call का उपयोग करते हैं कर सकते हैं: हालांकि यह अजीब लगता है कि आप के माध्यम से ऐसा करने में असमर्थ हैं

    static Expression BuildAny<TSource>(Expression<Func<TSource, bool>> predicate) 
    { 
        var overload = typeof(Queryable).GetMethods("Any") 
               .Single(mi => mi.GetParameters().Count() == 2); 
        var call = Expression.Call(
         overload, 
         Expression.PropertyOrField(projParam, "GroupsAssigned"), 
         predicate); 
    
        return call; 
    } 
    

    :

    // for Enumerable.Any<T>(IEnumerable<T>,Predicate<T>) 
    var overload = typeof(Enumerable).GetMethods("Any") 
               .Single(mi => mi.GetParameters().Count() == 2); 
    var call = Expression.Call(
        overload, 
        Expression.PropertyOrField(projParam, "GroupsAssigned"), 
        anyLambda);  
    

    Queryable.Any<T> लिए, आप इस एक विधि में रोल करने की आवश्यकता होगी एक सामान्य प्रश्न

    +0

    समाधान के लिए धन्यवाद, छः पत्रिकाएं। Expression.Call() बिल्कुल वही था जो मुझे चाहिए था। अपने प्रश्न का उत्तर देने के लिए, मैं इस मामले में एक सामान्य प्रश्न नहीं कर सकता क्योंकि मुझे संकलन समय में नहीं पता कि मेरे WHERE कथन में कितने और हिस्से होंगे। यह सब खोज फ़ॉर्म में उपयोगकर्ता द्वारा किए गए चयनों पर निर्भर करता है। अभिव्यक्ति वृक्ष का निर्माण एकमात्र वैध समाधान प्रतीत होता है। –

    +0

    धन्यवाद भगवान मैंने यह देखा, मेरी गलती थी कि मैं टाइपिंग (क्वेरी करने योग्य) .GetMethods ("कोई भी") एकल (मील => मील। गेट पैरामीटर()। गणना() == 2); ' के बजाय : 'टाइपऑफ (गणना योग्य) .GetMethods (" कोई भी ")। एकल (मील => मील। गेट पैरामीटर()। गणना() == 2);' –