2010-03-15 11 views
13

मान लीजिए मैं एक इकाई वस्तुइकाइयों के अभिव्यक्ति के लिए Linq पुनर्प्रयोग <चयन में समारोह <T, TResult> और कहाँ

public partial class Article 
{ 
    public Id 
    { 
     get; 
     set; 
    } 
    public Text 
    { 
     get; 
     set; 
    } 
    public UserId 
    { 
     get; 
     set; 
    } 
} 

एक लेख के कुछ गुणों के आधार पर के रूप में परिभाषित किया है कहता है, मैं निर्धारित करने के लिए करता है, तो लेख हटाया जा सकता है की जरूरत है किसी दिए गए उपयोगकर्ता द्वारा। इसलिए मैं जांच करने के लिए एक स्थिर विधि जोड़ता हूं। की तरह कुछ:

public partial class Article 
{ 
    public static Expression<Func<Article, bool>> CanBeDeletedBy(int userId) 
    { 
     //Add logic to be reused here 
     return a => a.UserId == userId; 
    } 
} 

तो अब मैं

using(MyEntities e = new MyEntities()) 
{ 
    //get the current user id 
    int currentUserId = 0; 

    e.Articles.Where(Article.CanBeDeletedBy(currentUserid)); 
} 

अब तक तो अच्छा कर सकते हैं। अब मैं CanBeDeletedBy में तर्क का पुन: उपयोग करने के लिए एक का चयन करें, की तरह कुछ कर रही है, जबकि हैं:

using(MyEntities e = new MyEntities()) 
{ 
    //get the current user id 
    int currentUserId = 0; 

    e.Articles.Select(a => new 
    { 
     Text = a.Text, 
     CanBeDeleted = ??? 
    }; 
} 

लेकिन कोई फर्क नहीं पड़ता कि मैं क्या करने की कोशिश, मैं चयन विधि में अभिव्यक्ति का उपयोग नहीं कर सकते। मुझे लगता है कि यह है कि मैं

e.Articles.Select(a => new 
    { 
     Text = a.Text, 
     CanBeDeleted = a => a.UserId == userId 
    }; 

कर सकते हैं तो मैं एक ही अभिव्यक्ति का उपयोग करने के लिए सक्षम होना चाहिए। अभिव्यक्ति को संकलित करने और

e.Articles.Select(a => new 
    { 
     Text = a.Text, 
     CanBeDeleted = Article.CanBeDeletedBy(currentUserId).Compile()(a) 
    }; 

करके इसे कॉल करने का प्रयास किया गया लेकिन यह काम नहीं करेगा।

काम करने के लिए इसे कैसे प्राप्त करें इस पर कोई विचार? या यदि यह संभव नहीं है, तो दोनों जगहों पर व्यावसायिक तर्क का पुन: उपयोग करने के विकल्प क्या हैं?

धन्यवाद

पेड्रो

+0

अभिव्यक्ति संकलन सही विकल्प है और यह संकलित करता है और मेरे लिए काम करता है। अगर यह मैं था, तो मैं संकलन को भी कारक बनाउंगा। आप क्या त्रुटि प्राप्त कर रहे हैं ? –

+0

हां, यह ठीक संकलित करता है, लेकिन एक NotSupportedException अपवाद फेंकता है: "LINQ अभिव्यक्ति नोड प्रकार 'Invoke' LINQ से इकाइयों में समर्थित नहीं है।" एक फनक में चयन के बाहर अभिव्यक्ति को संकलित करने का प्रयास किया और उसी परिणाम के साथ इसे अंदर उपयोग करें। – Pedro

+0

बीटीडब्ल्यू, अगर मैं एक सादा Func का उपयोग करता हूं, और इसका उपयोग करता हूं कहाँ विधि, फिर क्वेरी ग्राहक है, जो इच्छित उद्देश्य नहीं है पर निष्पादित किया जाएगा – Pedro

उत्तर

4

का दोबारा उपयोग अभिव्यक्ति पेड़ एक काले रंग की कला है, आप इसे कर सकते हैं, लेकिन आपको प्रतिबिंब में बहुत सारे कोड स्विच करने की आवश्यकता होगी और आप सभी स्थिर जांच खो देंगे। विशेष रूप से, गुमनाम प्रकारों के साथ काम करना एक दुःस्वप्न बन जाता है (हालांकि 4.0 में dynamic काम करने योग्य हो सकता है)।

आगे, यदि आप धोखा देते हैं और Expression.Invoke का उपयोग करते हैं, तो यह सभी प्रदाताओं द्वारा समर्थित नहीं है (सबसे महत्वपूर्ण रूप से .NET 3.5SP1 में ईएफ पर नहीं)।

जब तक यह एक बड़ा दर्द बिंदु नहीं है, तो मैं इसे डुप्लिकेशंस के साथ छोड़ दूंगा। या अभिव्यक्ति वृक्ष का पुनः उपयोग करने के लिए की आवश्यकता है?

+1

डॉन के लिए LINQ के साथ ठीक काम करता है '- तथ्य यह है कि आप एफई का उपयोग कर रहे याद किया टी वास्तव में अभिव्यक्ति पेड़ फिर से उपयोग करने के लिए की जरूरत है। यह सिर्फ सुरक्षा से संबंधित कोड की नकल नहीं की कोशिश करने के लिए किया गया था। लेकिन अब मैं के लिए यह करना होगा, और अगर मैं कोड बाद में refactor कर सकते हैं देखते हैं। धन्यवाद – Pedro

3

मैं क्या मैं PredicateBuilder जो LinqKit में एक वर्ग है और यह भी AsExpandable() http://www.albahari.com/nutshell/linqkit.aspx भाव का निर्माण करने के लिए प्रयोग किया जाता है और मैं उन्हें स्थिरता एक स्थिर वर्ग में संग्रहीत के रूप में

public readonly Expression<Func<T,bool>> 

है। प्रत्येक अभिव्यक्ति पिछले अभिव्यक्ति पर निर्माण कर रही थी जिससे डुप्लिकेशन की मात्रा कम हो गई।

मार्क ग्रेवल द्वारा पिछले प्रश्न के अनुसार, इस तरह की बात एक काला कला है, लेकिन शुक्र है कि अन्य कामों से बहुत सारे काम किए गए हैं।

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