2009-07-14 12 views
11

एक LINQ में रिटर्न कैसे आप एक डिफ़ॉल्ट मान है:अगर एक LINQ संस्थाओं के लिए क्वेरी इस तरह संस्थाओं अभिव्यक्ति के लिए कोई मान

var vote = (from vote in db.Vote where 
    vote.Voter.Id == user.Id 
    select v).FirstOrDefault(); 

आप कैसे एक DefaultIfEmpty मूल्य जोड़ सकता हूँ ताकि जब कोई वोट मैं है डी डिफ़ॉल्ट मान मिलता है?

उत्तर

1

मैं एक बहुत ही सरल दृष्टिकोण के लिए जा रहा समाप्त हो गया:

var vote = db.Vote.FirstOrDefault(v => v.Voter.Id == user.Id) ?? defaultVote; 
+1

एफवाईआई, यह आपके मूल प्रश्न को पूरा नहीं करता है। आपने स्पष्ट रूप से एक डिफ़ॉल्ट मान वापस करने के लिए कहा है, न कि नया मान न बनाएं यदि यह पहले से मौजूद नहीं है। (यह ठीक कोड है, जो आपने पूछा वह नहीं करता है।) – BenSwayne

5

अपनी खुद की विस्तार विधि जोड़ें। उदाहरण के लिए:

public static class Extension 
{ 
    public static T FirstOrDefault(this IEnumerable<T> sequence, T defaultValue) 
    { 
     return sequence.Any() ? sequence.First() : defaultValue; 
    } 
} 
दायरे में उस वर्ग के साथ

, आप कह सकते हैं:

var vote = (from vote in db.Vote where 
    vote.Voter.Id == user.Id 
    select v).FirstOrDefault(yourDefaultValue); 
बेशक

, अपने विधि भी, एक अधिभार कि रिटर्न डिफ़ॉल्ट (टी) हो सकता है कि अगर था क्या तुम कहाँ खोज रहे हैं बिल्ट-इन एक्सटेंशन क्लास में पहले से ही एक डिफ़ॉल्ट IfEmpty एक्सटेंशन विधि परिभाषित की गई है, इसलिए मैंने "FirstOrDefault" उदाहरण में विधि का नाम दिया, जो एक बेहतर फिट जैसा प्रतीत होता है।

+0

DefaultIfEmpty() पहले से ही एक विस्तार विधि :) के रूप में मौजूद http://msdn.microsoft.com/en-us/library/bb355419.aspx –

+0

आप कर रहे हैं ठीक है, मैं उदाहरण एक का उपयोग करने के संपादित बेहतर नाम – driis

+0

जब मैं पहले से ही उस उद्देश्य के लिए डिज़ाइन किया गया था, तो मुझे फर्स्टऑर्डडिफॉल्ट को फिर से लिखना क्यों चाहिए? – Pablo

3

पहले तत्व प्राप्त करने से पहले डिफ़ॉल्ट मान जोड़ें।

var vote = db.Vote 
    .Where(v => v.Voter.Id == user.Id) 
    .DefaultIfEmpty(defaultVote) 
    .First(); 

ध्यान दें कि आप अब सुरक्षित रूप से First() बजाय FirstOrDefault() उपयोग कर सकते हैं।

अद्यतन

एंटिटी को LINQ DefaultIfEmpty() विस्तार विधि को नहीं पहचानता। लेकिन आप सिर्फ नल कोलेसिंग ऑपरेटर का उपयोग कर सकते हैं।

var vote = (db.Vote 
    .Where(v => v.Voter.Id == user.Id) 
    .FirstOrDefault()) ?? defaultVote; 
+1

यदि कोई डिफ़ॉल्ट जोड़ते समय आप पहले उपयोग कर सकते हैं, तो FirstOrDefault बिल्कुल क्यों मौजूद है? – Pablo

+0

कई LINQ ऑपरेटर कुछ हद तक अनावश्यक हैं - अनुक्रम। किसी भी() को अनुक्रम के रूप में फिर से लिखा जा सकता है। गणना()> 0. आप अनुक्रम का उपयोग कर सकते हैं। जहां (item => हालत (आइटम))। पहला() या अनुक्रम। सबसे पहले (आइटम => हालत (वस्तु))। आप जॉइन या नेस्टेड प्रश्नों का उपयोग कर सकते हैं। कोड लिखते समय आप लूप के लिए उपयोग, कर सकते हैं और उपयोग कर सकते हैं। आप गोटो का भी उपयोग कर सकते हैं। आमतौर पर दिए गए लक्ष्य को प्राप्त करने का एक ही तरीका नहीं है। –

+3

ध्यान दें कि seq.Count() (उन ऑब्जेक्ट्स के लिए जो आईसीओलेक्शन लागू नहीं करते हैं) पूर्ण अनुक्रम की गणना करेंगे जबकि seq.Any() जैसे ही कोई तत्व मिलेगा, वापस आ जाएगा। समान, लेकिन अलग।:) – dahlbyk

17

एक और दृष्टिकोण, अगर Vote एक संदर्भ प्रकार है और इस तरह अपनी डिफ़ॉल्ट मान के रूप अशक्त का उपयोग करता है, अशक्त कोलेसिंग ऑपरेटर का उपयोग करने के लिए किया जाएगा एक जवाब यहाँ की सिफारिश की थी जो था कि बाद मिट:

var vote = (from vote in db.Vote 
      where vote.Voter.Id == user.Id 
      select v).FirstOrDefault(); 
if (vote == null) { 
    vote = new Vote() { .... }; 
    db.AddToVoteSet(vote); 
} 
0

किसी कारण से अगर मैं एक सूची में resultset बारी है, Defaultifempty() काम करता है अगर मैं inadve है मैं नहीं जानता पूरी तरह से लिंक क्षेत्र में पार हो गया।

var results = (from u in rv.tbl_user 
         .Include("tbl_pics") 
         .Include("tbl_area") 
         .Include("tbl_province") 
         .ToList() 
         where u.tbl_province.idtbl_Province == prov 
         select new { u.firstName, u.cellNumber, u.tbl_area.Area, u.ID, u.tbl_province.Province_desc, 
            pic = (from p3 in u.tbl_pics 
              where p3.tbl_user.ID == u.ID 
              select p3.pic_path).DefaultIfEmpty("defaultpic.jpg").First() 
               }).ToList(); 
संबंधित मुद्दे