2012-06-04 12 views
60

मैं इसLinq: जहां खंड के स्थिति जोड़ने सशर्त

(from u in DataContext.Users 
     where u.Division == strUserDiv 
     && u.Age > 18 
     && u.Height > strHeightinFeet 
     select new DTO_UserMaster 
     { 
     Prop1 = u.Name, 
     }).ToList(); 

मैं उम्र, चाहे उन परिस्थितियों इस क्वेरी चलाने विधि के लिए प्रदान किया गया के आधार पर ऊँचाई की तरह विभिन्न स्थितियों में जोड़ना चाहते हैं की तरह एक प्रश्न। सभी स्थितियों में उपयोगकर्ता डिवीजन शामिल होगा। यदि उम्र की आपूर्ति की गई थी तो मैं इसे क्वेरी में जोड़ना चाहता हूं। सिमिलरी, अगर ऊंचाई प्रदान की गई तो मैं इसे भी जोड़ना चाहता हूं।

यदि यह एसक्यूएल प्रश्नों का उपयोग करके किया जाना था तो मैं स्ट्रिंग बिल्डर का उपयोग मुख्य स्ट्रस्क्लुएल क्वेरी में जोड़ने के लिए करता था। लेकिन यहां लिंकक में मैं केवल एक आईएफ शर्त का उपयोग करने के बारे में सोच सकता हूं जहां मैं एक ही प्रश्न तीन बार लिखूंगा, प्रत्येक आईएफ ब्लॉक में अतिरिक्त शर्त होगी। क्या ऐसा करने के लिए इससे अच्छा तरीका है?

आपके समय के लिए धन्यवाद ..

+0

सुंदर सवाल! एक और सुन्दर उत्तर के साथ, एक अच्छी तरह से phrased शीर्षक के साथ! – Irfan

उत्तर

108

आप ToList() फोन नहीं है, तो और डीटीओ प्रकार अपने अंतिम मानचित्रण, आप अंत में के रूप में तुम जाओ Where खंड में जोड़ सकते हैं, और निर्माण के परिणाम:

var query = from u in DataContext.Users 
    where u.Division == strUserDiv 
    && u.Age > 18 
    && u.Height > strHeightinFeet 
    select u; 

if (useAge) 
    query = query.Where(u => u.Age > age); 

if (useHeight) 
    query = query.Where(u => u.Height > strHeightinFeet); 

// Build the results at the end 
var results = query.Select(u => new DTO_UserMaster 
    { 
    Prop1 = u.Name, 
    }).ToList(); 

यह अभी भी केवल एक में परिणाम होगा डेटाबेस में एकल कॉल, जो एक पास में क्वेरी लिखने के रूप में प्रभावी रूप से प्रभावी होगा।

+0

क्या मुझे "var query = .." कथन में सभी स्थितियों को रखने की ज़रूरत है? – user20358

+1

@ user20358 नहीं - ऊपर लिखा गया तरीका ठीक काम करता है। –

+2

बाद में जहां स्थितियों को OR या AS के रूप में समेकित किया जाता है? – Vi100

12

एक विकल्प।

bool? age = null 

(from u in DataContext.Users 
      where u.Division == strUserDiv 
      && (age == null || (age != null && u.Age > age.Value)) 
      && u.Height > strHeightinFeet 
      select new DTO_UserMaster 
      { 
      Prop1 = u.Name, 
      }).ToList(); 

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

+0

विश्वास नहीं कर सकता मैंने इस बारे में नहीं सोचा था। – phil

2

यहां एक ही काम करने के लिए मेरा कोड है। यह मेरी डब्ल्यूसीएफ एसओएपी वेब सेवा एपीआई पर एक विधि है।

public FruitListResponse GetFruits(string color, bool? ripe) 
    { 
     try 
     { 
      FruitContext db = new FruitContext(); 
      var query = db.Fruits.Select(f => f); 
      if (color != null) 
      { 
       query = query.Where(f => f.Color == color); 
      } 
      if (ripe != null) 
      { 
       query = query.Where(f => f.Ripe == ripe); 
      } 
      return new FruitListResponse 
      { 
       Result = query.Select(f => new Fruit { Id = f.FruitId, Name = f.Name }).ToList() 
      }; 
     } 
     catch (Exception e) 
     { 
      return new FruitListResponse { ErrorMessage = e.Message }; 
     } 
    } 

आधार क्वेरी Select(f => f) जो मूल रूप से सब कुछ का मतलब है, और Where खंड वैकल्पिक रूप से इसे से जुड़े रहे हैं। अंतिम Select वैकल्पिक है। मैं डेटाबेस पंक्तियों ऑब्जेक्ट्स को "फल" ऑब्जेक्ट्स में परिवर्तित करने के लिए उपयोग करता हूं।

+1

अच्छा स्पष्टीकरण – xDJR1875

7

मैं आमतौर पर विधि श्रृंखला का उपयोग करता हूं लेकिन एक ही समस्या है। और यहां विस्तार है I

public static IQueryable<T> ConditionalWhere<T>(
     this IQueryable<T> source, 
     Func<bool> condition, 
     Expression<Func<T, bool>> predicate) 
    { 
     if (condition()) 
     { 
      return source.Where(predicate); 
     } 

     return source; 
    } 

यह श्रृंखला ब्रेक से बचने में मदद करता है। साथ ही ConditionalOrderBy और ConditionalOrderByDescending सहायक हैं।

+0

सहायक, लेकिन क्या आप कृपया इसका उपयोग करने के लिए एक उदाहरण जोड़ देंगे। – Suncat2000

+1

यह होना चाहिए: var fruit = प्रतीक्षा db.Fruits । कंडिशनवेयर (() => रंग! = शून्य, एफ => एफ। रंग == रंग) । कंडिशनवेयर (() => परिपक्व! = शून्य, f => f.Ripe == ripe) .ToListAsync(); –

+1

महान काम करता है! धन्यवाद! मैंने * कंडीशन * के लिए एक फंक्शन के बजाए एक साधारण बूलियन वैल्यू के रूप में ओवरलोड किया, जिससे इसे अधिक सहज बना दिया जा सके जहां एक प्रतिनिधि अनावश्यक जटिलता को जोड़ देगा। मैं इस विस्तार विधि का बहुत बार उपयोग करता हूं और आपके समाधान की बहुत सराहना करता हूं। – Suncat2000

2

, बस मैं

public IList<ent_para> getList(ent_para para){ 
    db.table1.Where(w=>(para.abc!=""?w.para==para.abc:true==true) && (para.xyz!=""?w.xyz==para.xyz:true==true)).ToList(); 
} 
0

के रूप में मेरी जहां खंड में यह उपयोग कर रहा हूँ कुछ condtion के आधार पर जहां हालत जोड़ने ...

from u in DataContext.Users 
where u.Division == strUserDiv 
&& u.Age != null ? u.Age > 18 : 1== 1 
&& u.Height != null ? u.Height > 18 : 1== 1 
&& u.Height != null ? u.Height > 18 : 1== 1 
select new DTO_UserMaster 
     { 
     Prop1 = u.Name, 
     }).ToList();