2015-09-16 13 views
6

कहें कि मेरे पास यह है कि मैं समूह 42 में प्रत्येक व्यक्ति को प्राप्त करना चाहता हूं, लेकिन मैं डेटाबेस में प्रत्येक अद्वितीय पहले नाम का एक IQueryable प्राप्त करना चाहता हूं (पीएस - मुझे पता है कि मैं चयन के बाद AsQueryable() को कॉल कर सकता हूं लेकिन यह नहीं है - मैं कर रहा हूँ करने में रुचि रखते मैं डेटाबेस अलग, कार्यक्रम नहीं) निष्पादित करना चाहते हैं:ईएफ - एक IQueryable पर DistinctBy?

MyEfContextContainer db = new MyEfContextContainer(); 
IQueryable<string> uniqueFirstNames = 
    db.People 
    .Where(x=> x.GroupId == 42) 
    .DistinctBy(c=> c.FirstName) 
    .Select(c=> c.FirstName); 

मैं क्या की कैसे एफई/LINQ संस्थाओं को DistinctBy विस्तार विधि संभालती है बता सकते हैं, एक दुकान क्वेरी है निष्पादित किया गया जब DistinctBy का आह्वान किया जाता है और डेटाबेस में सभी आइटमों की एक सूची जो कहां से पुनर्प्राप्त होती है, से मेल खाता है, तो सी # डिस्टिंटबी विधि से एक आईनंबरबल लौटाता है जो डिस्टिंटबी को भेजे गए अभिव्यक्ति से मेल खाता है।

यदि सूची में लाखों नाम हैं तो यह बहुत अक्षम है।

मुझे यह कुशलतापूर्वक करने में सक्षम होने में दिलचस्पी है, उम्मीद है कि स्टोर क्वेरी केवल तालिका में सभी अद्वितीय फर्स्ट नामों का परिणाम सेट लौटा दे। उदाहरण के लिए, मैं उस IQueryable को एक भंडार के हिस्से के रूप में वापस लौटना चाहता हूं, जहां प्रदर्शन के कारण यह ठीक नहीं है कि लाखों वस्तुओं को पकड़ लिया गया है और विशिष्ट मूल्यों को वापस करने के लिए डिस्टिंट द्वारा संसाधित किया गया है। इससे एक अस्वीकार्य स्तर पर अनुरोध प्रसंस्करण का समय बढ़ जाएगा।

क्या ऐसा करने का कोई तरीका है? क्या मैं कुछ भूल रहा हूँ? यह केवल एक साधारण उदाहरण है, स्पष्ट रूप से वास्तविक अनुप्रयोग ऑब्जेक्ट्स में स्ट्रिंग की तुलना में अधिक जटिल भंडार के लिए एक क्वेरी का विषय होगा।

उत्तर

3

IQueryable के साथ आप यह अपने आप को क्या करना है:

db.People 
    .Where(x => x.GroupId == 42) 
    .GroupBy(c => c.FirstName) 
    .Select(g => g.FirstOrDefault()); 

MoreLinq के DistinctBy विधि IEnumerable<T> पर एक विस्तार विधि है, तो यह एक IQueryable<T> स्वीकार करता है, लेकिन विधि के अंदर यह एक IEnumerable<T> के रूप में कार्य करता है।

public static IQueryable<TSource> DistinctBy<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector) 
    { 
     return source.GroupBy(keySelector).Select(x => x.FirstOrDefault()); 
    } 

एक संपत्ति है, उदा के आधार पर एक अलग चयन करने के लिए: यह मैं इस विस्तार लिखा db.People.AsEnumerable().DistinctBy()

+0

गोचा, मुझे पता है कि मैं ऐसा कर सकता हूं लेकिन मुझे यकीन नहीं है कि यह मेरे उपयोग के मामले में फिट बैठता है ... मुझे एक नज़र डालने दो। – Pugz

5

कर के रूप में एक ही प्रभाव है आईडी, मैं बस कॉल करता हूं:

res = res.DistinctBy(x => x.Id);