2012-09-14 16 views
16

मैं LINQ करने वाली एसक्यूएल और सब कुछ अच्छी तरह से जा रहा था जब तक कुछ अजीब हुआ के बारे में सीख रहा हूँ: नॉर्थविंड dabatase मैंने लिखा का उपयोग करDISTINCT() और orderby मुद्दा

मैं distinct का एक उदाहरण करने की कोशिश की, तो, निम्न क्वेरी:

var query = 
    from o in db.Orders 
    orderby o.CustomerID 
    select new 
    { 
     o.CustomerID 
    }; 

अगर मैं query में संग्रहीत क्वेरी के लिए LINQ करने वाली एसक्यूएल द्वारा उत्पन्न एसक्यूएल प्रिंट यह इस तरह दिखता है:

SELECT [t0].[CustomerID] 
FROM [dbo].[Orders] AS [t0] 
ORDER BY [t0].[CustomerID] 

तो, सामान्य रूप से, प्रश्न Orders तालिका में क्रमशः क्रमशः क्रमशः Order के लिए सभी CustomerID लाता है।

लेकिन! अगर मैं Distinct() विधि इस तरह का उपयोग करें:

var query = (
    from o in db.Orders 
    orderby o.CustomerID 
    select new 
    { 
     o.CustomerID 
    }).Distinct(); 

क्वेरी Distinct खंड के अपेक्षित परिणाम लाता है, लेकिन CustomerID रों आदेश दिया नहीं कर रहे हैं के बावजूद मैं orderby o.CustomerID लिखा है!

SELECT DISTINCT [t0].[CustomerID] 
FROM [dbo].[Orders] AS [t0] 

हम देख सकते हैं ** ORDER BY खंड याद आ रही है:

इस दूसरे LINQ क्वेरी के लिए SQL क्वेरी निम्नलिखित है। ऐसा क्यों है?

ORDER BY क्लॉज गायब हो जाता है जब मैं Distinct() विधि का उपयोग करता हूं?

+1

एक अलग रूप में लैम्ब्डा वाक्य रचना इस तरह के प्रश्नों के लिए बहुत सरल है के रूप में: 'वर क्वेरी = db.Orders.Select (ओ => ओ .CustomerId)। डिस्टिंक(); ' – asawyer

उत्तर

28

Queryable.Distinct documentation से;

अपेक्षित व्यवहार यह है कि यह स्रोत में अद्वितीय वस्तुओं का एक अनुक्रमित अनुक्रम देता है।

दूसरे शब्दों में, जब आप Distinct() का उपयोग करते हैं तो मौजूदा IQueryable का कोई भी आदेश खो जाता है।

आप जो चाहते हैं वह शायद कुछ और है, ऑर्डरबी() के बाद अलग() किया जाता है;

var query = (from o in db.Orders 
      select new 
      { 
       o.CustomerID 
      }).Distinct().OrderBy(x => x.CustomerID); 
8

कोशिश सदस्यों उलटफेर अलग होने के बाद OrderBy जगह। ,

db.Orders.Select(o=>o.CustomerId).Distinct().OrderBy(id=>id); 

यह वैसे भी Enumerable Linq में क्वेरी स्थापित करने के लिए और अधिक कुशल तरीका होगा क्योंकि OrderBy उसके बाद ही अद्वितीय आइटम पर के सभी पर नहीं काम करते हैं और चाहते हैं: आप विधि श्रृंखलन पर वापस लौटने करना होगा उन्हें। इसके अलावा, MSDN के अनुसार, संख्यात्मक। डिस्टिंट तत्वों के रिटर्न ऑर्डर की गारंटी नहीं देता है, इसलिए समर्पण से पहले ऑर्डर करना व्यर्थ है।

+3

नहीं, यह डिज़ाइन द्वारा है। – asawyer

+0

... हां यह है: http://msdn.microsoft.com/en-us/library/system.linq.enumerable.distinct.aspx। सवाल यह है कि, डिस्टिंट इनपुट तत्वों के क्रम को क्यों बनाए रखता है, जब यह केवल उपज-वापसी से आसानी से हो सकता है? – KeithS

+2

@ किथ्स क्या आपने अपना लिंक पढ़ा ... "परिणाम अनुक्रम अनियंत्रित है।" जब यह डिज़ाइन में बनाया गया है तो यह एक बग नहीं है। –

3

अलग के उपयोग के कारण, लौटे सूची के क्रम इसकी गारंटी नहीं है। LinqToSql यह पहचानने के लिए पर्याप्त स्मार्ट है, क्योंकि यह इसे अनदेखा करता है।

आप अपने अलग होने के बाद से आदेश देते हैं, सब कुछ के रूप में आप की इच्छा नहीं होगा।

var query = (from o in db.Orders 
      select new 
      { 
       o.CustomerID 
      }).Distinct().OrderBy(o => o.CustomerID); 

या

var query = db.Orders.Select(o => o.CustomerID).Distinct().OrderBy(o => o.CustomerID); 

कृपया स्पष्टीकरण के लिए यह लेख देखें:

http://programminglinq.com/blogs/marcorusso/archive/2008/07/20/use-of-distinct-and-orderby-in-linq.aspx

1

आप इस counstruction साथ orderBy और विशिष्ट अनुकरण कर सकते हैं:

var distinctItems = employees.GroupBy(x => x.EmpID).OrderBy(x => x).Select(y => y.First());