2012-02-29 13 views
25

हम एक वस्तुLINQ प्रश्नों

public class SomeObject 
{ 
    public Name {get;set;} 
    public City {get;set;} 
    public State {get;set} 
    //various other parameters. Let's say there's ~20 
} 

यह गतिशील स्रोत कोड के रखता बिना नए LINQ प्रश्नों बनाने के लिए संभव है? इसके बजाए, क्वेरी पैरामीटर एक XML संरचना से आते हैं जो डेटाबेस में संग्रहीत और अद्यतन किया जाता है।

var result = from i in someObj 
      where 
      //XML requests Name = 'Bob'...so append this where clause 
      name = 'Bob' 

यह किया जा सकता है?

+1

ऐसा करने के कुछ अलग तरीके हैं। क्या यह हमेशा संपत्ति == मूल्य होगा। कम से कम, बराबर से अधिक नहीं हैं? क्या एक्सएमएल एक से अधिक मान निर्दिष्ट कर सकता है? 'नाम = 'बॉब' || नाम = 'फ्रेड'। क्या शर्तें केवल && के साथ संयुक्त हैं? 'नाम = 'बॉब' और राज्य = 'ओएच'। या शर्तों के साथ संयुक्त किया जा सकता है || 'नाम = 'बॉब' || राज्य = 'ओएच'। एक समाधान प्रस्तावित करने से पहले इन सभी को ध्यान में रखा जाना चाहिए। – cadrell0

+1

प्रश्न में स्पष्टता की कमी है; यह प्रदान नहीं करता है कि एक्सएमएल संरचना में सशर्त अभिव्यक्तियां होंगी (केवल वांछित मूल्यों के मिलान के बजाय, 'नाम =' बॉब 'के रूप में प्रतीत होता है)। यह बेवकूफ और अनुपयोगी है कि किसी को यह पता चल रहा है कि वह इस गुम जानकारी का अनुमान नहीं लगाए गए सभी उत्तरों को गोल करने और नीचे जाने के लिए उपयुक्त है। – Douglas

+0

@ कैडरेल 0 - अधिक जटिल प्रश्न बहुत अच्छे जोड़े होंगे। मैंने केवल एक जहां खंड के साथ सवाल शुरू करने की कोशिश की। मुझे नहीं पता था कि यह अपने आप में और बहुत ही जटिल समाधान होगा। उत्तरों के आधार पर, कार्यों को प्राप्त करने के लिए एक संपूर्ण पुस्तकालय उपलब्ध है। स्कॉटगु द्वारा गतिशील LINQ आशाजनक लग रहा है। –

उत्तर

89

यहाँ अभिव्यक्ति के पेड़ के साथ एक समाधान है:

var param = Expression.Parameter(typeof(SomeObject), "p"); 
var exp = Expression.Lambda<Func<SomeObject, bool>>(
    Expression.Equal(
     Expression.Property(param, "Name"), 
     Expression.Constant("Bob") 
    ), 
    param 
); 
var query = someObj.Where(exp); 

मैं जानता हूँ कि यह और अधिक जटिल है, लेकिन इस समय में उपयोगी हो सकता है।

+10

यह उत्तर अधिक प्यार के लायक है। – Askolein

+3

+1 क्योंकि अभिव्यक्ति पेड़ पहले समझने में थोड़ा मुश्किल हो सकता है, लेकिन वे इस समस्या के लिए एक अच्छा समाधान हैं। एक बार जब आप प्रारंभिक उदाहरणों को पीछे छोड़ देते हैं तो वहां शून्य मूल्यों को संभालने के लिए देखें और सुनिश्चित करें कि आपके अभिव्यक्तियों में उपयोग किए जाने वाले प्रकार एक दूसरे से मेल खाते हैं। आपके प्रश्नों के स्रोत "गतिशील" के आधार पर (उदा।, सभी अभिव्यक्तियों। कॉन्स्टेंट्स() स्ट्रिंग के रूप में आते हैं, भले ही उनकी तुलना किसी इंटेल से की जाती है) तो आपको कुछ अतिरिक्त रूपांतरण करने की आवश्यकता हो सकती है। यह एमएसडीएन लेख भी एक अच्छा रेफरी है - http://msdn.microsoft.com/en-us/library/bb882637.aspx –

+1

मैं तुमसे प्यार करता हूँ आदमी।आपने इस गड़बड़ी को कोड की दो पंक्तियों में सरलीकृत किया है। मुझे इंगित करें कि 'कुछ ओबीजे' को 'कहाँ (एक्सपी) ' –

2

हाँ, यह वास्तव में बहुत आसान है:

var name = GetBobNameFromXml(); 
var result = someObj.Where(i => i.Name == name); 

तुम भी चुन सकते हैं या नहीं, मापदंड टुकड़ों लागू करने के लिए।

var result = someObj; 
var name = xmlCriteria.Name; 
if(!string.IsNullOrEmpty(name)) 
{ 
    result = result.Where(i => i.Name == name); 
} 
// follow the same pattern for city, state, etc. 

तुम भी एक पैटर्न कसौटी funcs का एक नाम-keyed शब्दकोश का उपयोग करता है, if बयान के एक झुंड से बचने के लिए इस्तेमाल कर सकते हैं।

foreach(var criterionPair in xmlCriteria) 
{ 
    var value = criterionPair.Value; 
    result = result.Where(i => propGetters[criterionPair.PropertyName](i, value)); 
} 

असल में, आप इन पंक्तियों के साथ बहुत कुछ कर सकते हैं। यदि आप अपनी स्थिति के लिए विशेष रूप से एक उत्तर चाहते हैं, तो आपको एक और विशिष्ट प्रश्न प्रदान करना होगा।

+0

नहीं, आप उसका प्रश्न चूक गए। आप टेक्स्ट फ़ील्ड से linq क्वेरी कैसे बनाते हैं? – jcolebrand

+0

@jcolebrand: क्या आप स्पष्टीकरण दे सकते हैं कि "टेक्स्ट फ़ील्ड से linq क्वेरीज़" बनाते हैं? जहां तक ​​मैं कह सकता हूं, प्रश्न के अस्पष्टता पर विचार करते हुए मैंने प्रश्न का उत्तर दिया है और आशा की जा सकती है। – StriplingWarrior

10

हो सकता है कि गतिशील Linq आप मदद कर सकते हैं: Dynamic linq part 1: Using the linq dynamic query library

query = query.Where("Id = 123 And Age > 18"); 

या फिर आप अपने LINQ क्वेरी सीधे हेरफेर कर सकते हैं:

query = query.Where(x=>x.Id == 5); 
+0

हां, लेकिन क्या आप यह दिखाने के लिए एक उदाहरण कोड पेस्ट कर सकते हैं कि यह गतिशील linq का उपयोग करके कैसे काम करेगा? – jcolebrand

+0

आप कहां खंड में स्ट्रिंग का उपयोग कर सकते हैं, उदा। क्वेरी = क्वेरी। जहां ("आईडी = 123 और आयु> 18"); – Antineutrino

+5

मेरा शब्द आदमी, क्या मुझे आपके लिए संपादन करने की ज़रूरत है? अपनी पोस्ट संपादित करें और उस जानकारी को शामिल करें। फिर अपवॉट प्राप्त करें। फिर gamification मिलता है। – jcolebrand

26

आप सबसे निश्चित रूप से Dynamic Linq पर एक नज़र लेने के लिए जो की अनुमति देगा चाहता हूँ आप क्वेरी शर्तों को पाठ के रूप में परिभाषित करने के लिए।

गतिशील रूप से परिस्थितियों को जोड़ने के लिए, आप समान वाक्यविन्यास का उपयोग कर क्वेरी में स्थितियां जोड़ सकते हैं;

if(CategoryIsImportant) 
    myQuery = myQuery.Where("CategoryId=2"); 

ये सभी (काफी आसानी से) अपनी पसंद का एक XML प्रारूप में एन्कोड कर सकते हैं।

+0

'कहां ("कुछ टेक्स्ट")' यूप। आपने उस अवधारणा को खींचा जिसे मैं प्राप्त करना चाहता हूं। –

+5

यह एक पुरानी पोस्ट है, इसलिए यह इस विशिष्ट प्रश्न के लिए प्रासंगिक नहीं हो सकती है, लेकिन डायनामिक लिंक ढांचे की अंतर्निहित विशेषता नहीं है। इसे स्रोत कोड के रूप में जारी किया गया था जिसे आप अपने एप्लिकेशन में डाउनलोड और संकलित कर सकते हैं (https://github.com/kahanu/System.Linq.Dynamic)। आपके आवेदन के आधार पर यह उपयुक्त नहीं हो सकता है, इसलिए बस इसके बारे में कुछ जागरूकता बढ़ाना चाहती थी। –

6

मेरा मानना ​​है कि आप वास्तव में Expression Trees में खुदाई करने के लिए होगा। मैंने इसमें बहुत दूर खोला नहीं है, इसलिए मैं आपके लिए नमूना नहीं बना सकता, लेकिन मुझे पता है कि आप अपने प्रश्नों को गतिशील रूप से बनाने के लिए अभिव्यक्ति पेड़ का उपयोग कर सकते हैं और फिर कॉल करने के लिए कॉम्पाइल (कोड में) कॉल कर सकते हैं।

वास्तव में, यहाँ एक बेहतर लिंक Building Dynamic Queries with Expression Trees है। यह आपको वही देना चाहिए जो आप चाहते हैं, और यह क्या है इसके लिए काफी संक्षेप में है। यह एक अच्छा उदाहरण के रूप में कार्य करना चाहिए आप

+0

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

+4

यह क्यों कम किया गया था? यह निश्चित रूप से समस्या को फिट करने लगता है, इसलिए मैं डाउनवोट के कारण की सराहना करता हूं? –

+1

अभिव्यक्ति पेड़ - पूरे परिवार के लिए मजेदार :) उप-मतदान क्योंकि किसी भी अन्य समाधान में से कोई भी उनका उल्लेख नहीं करता है। –

4

हों :) मुझे लगता है कि आप वैकल्पिक फिल्टर लागू करने के लिए, अपने XML की सामग्री के आधार चाहता हूँ। StriplingWarrior द्वारा उदाहरण पर जारी रखने के लिए:

var name = GetNameFromXml(); 
var city = GetCityFromXml(); 
var state = GetStateFromXml(); 

var result = someObj; 
if (name != null) 
    result = result.Where(i => i.Name == name); 
if (city != null) 
    result = result.Where(i => i.City == city); 
if (state != null) 
    result = result.Where(i => i.State == state); 

इस तरह, आप फिल्टर के किसी भी संख्या (कोई नहीं से सभी तीन के लिए) क्या वास्तव में अपने XML में निर्दिष्ट किया जाता है पर निर्भर करता है को लागू करने की जाएगी।

19

यह मेरे अपने प्रश्न के आधार पर यह बताने के लिए है, लेकिन कुछ मामलों में आप गतिशील Linq की जरूरत नहीं है और केवल यह कर सकते हैं के लिए मुश्किल है ...

var result = from o in someObj 
      where (Name == null || o.Name == Name) 
      && (City == null || o.City == City) 
      && (State == null || o.State == State) 
      select o; 

यह अनिवार्य रूप से फ़िल्टर किए जा रहे जब प्रश्न में पैरामीटर रिक्त है से डेटा नहीं कर पाएगा। और यह अभी भी सी # में शॉर्ट सर्किटिंग व्यवहार के लिए धन्यवाद करता है।

+2

आपके आइडिया ने मुझे जटिल गतिशील लिंक पुस्तकालयों के बिना मेरे मुद्दे को हल करने में अग्रणी भूमिका निभाई। इसे मूल तरीके से हल किया। धन्यवाद – Ananda

+0

यह मेरे लिए अच्छा काम करता है। मैं भूल गया कि हम एसक्यूएल संग्रहीत प्रक्रियाओं में ऐसा करते थे, इसलिए यह देखना आसान है कि यह लिंक में क्यों काम करेगा। – Caverman

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