2012-05-23 13 views
42

का उपयोग कैसे करें मैं एफई वर्ग एक डेटाबेस (सरलीकृत) से ली गईLINQ अलग() के साथ कई क्षेत्रों

class Product 
{ 
    public string ProductId; 
    public string ProductName; 
    public string CategoryId; 
    public string CategoryName; 
} 

ProductIdप्राथमिक कुंजी तालिका के है निम्नलिखित है।

डीबी डिजाइनर द्वारा किए गए एक खराब डिजाइन निर्णय के लिए (मैं इसे संशोधित नहीं कर सकता), मेरे पास इस तालिका में CategoryId और CategoryName है।

मैं (अलग) के रूप में CategoryIdमूल्य और CategoryName रूप पाठ के साथ एक DropDownList की जरूरत है।

product.Select(m => new {m.CategoryId, m.CategoryName}).Distinct(); 

जो तार्किक रूप से यह CategoryId और CategoryName गुण के रूप में के साथ एक अनाम वस्तु बनाना चाहिए: इसलिए मैं निम्नलिखित कोड लागू होता है। Distinct() गारंटी देता है कि कोई डुप्लिकेट जोड़ी नहीं है (CategoryId, CategoryName)।

लेकिन असल में यह काम नहीं करता है। जहां तक ​​मुझे लगता है कि Distinct() केवल तभी काम करता है जब संग्रह में केवल एक फ़ील्ड है अन्यथा यह केवल उन्हें अनदेखा करता है ... क्या यह सही है? क्या कोई कामकाज है? धन्यवाद!

अद्यतन

क्षमा product है:

product.GroupBy(d => new {d.CategoryId, d.CategoryName}) 
     .Select(m => new {m.Key.CategoryId, m.Key.CategoryName}) 
+0

'संग्रह में सिर्फ एक क्षेत्र है' अतर्कसंगत है। आपका क्या अर्थ है? – leppie

+0

@leppie मेरा अनुमान है, उसका मतलब है कि एक मूल्य पर प्रक्षेपण करते समय, एक अज्ञात प्रकार नहीं (जिसमें एक से अधिक फ़ील्ड होते हैं)। – sehe

+0

"डीबी डिजाइनर द्वारा किए गए खराब डिजाइन निर्णय के लिए (मैं इसे संशोधित नहीं कर सकता)"। आप शायद डेटाबेस को नहीं बदल सकते हैं, लेकिन इसका मतलब यह नहीं है कि आप इसे अपने ईएफ मॉडल में ठीक नहीं कर सकते हैं। यह ईएफ की धड़कन है। – Steven

उत्तर

11

अलग() की गारंटी देता है कि:

List<Product> product = new List<Product>(); 

मैं Distinct() रूप में एक ही परिणाम प्राप्त करने के लिए एक विकल्प रास्ता मिल गया कोई डुप्लिकेट जोड़ी नहीं है (Category आईडी, श्रेणीएन एएमई)।

- ठीक है कि

बेनामी प्रकार 'जादुई' Equals को लागू करने और GetHashcode

मैंने कहीं एक और त्रुटि मान। मामले की संवेदनशीलता? उत्परिवर्ती कक्षाएं? गैर तुलनीय खेतों?

+0

जो कुछ मैं करता हूं, लेकिन नीचे दिया गया जवाब नहीं कहता है।/मुझे उलझन में – leppie

+0

@Ieppie http://stackoverflow.com/questions/543482/linq-select-distinct-with-anonymous-types –

+0

@ राफेल अलाथॉस: मैंने अभी भी इसकी पुष्टि की है, मैन्युअल रूप से :) – leppie

33

मुझे लगता है कि आप किसी सूची में विधि कॉल की तरह अलग-अलग उपयोग करते हैं। आपको अपनी ड्रॉपडाउनलिस्ट के लिए डेटासोर्स के रूप में क्वेरी के परिणाम का उपयोग करने की आवश्यकता है, उदाहरण के लिए इसे ToList के माध्यम से इसे भौतिक रूप से भरकर।

var distinctCategories = product 
         .Select(m => new {m.CategoryId, m.CategoryName}) 
         .Distinct() 
         .ToList(); 
DropDownList1.DataSource  = distinctCategories; 
DropDownList1.DataTextField = "CategoryName"; 
DropDownList1.DataValueField = "CategoryId"; 
+9

हाँ मैं इसका उपयोग करता हूं, यह काम नहीं करता है मेरा मामला ... – CiccioMiami

+1

@CiccioMiami upvoters, सुनिश्चित करें कि आप इस उत्तर को केवल अनाम प्रकारों पर लागू कर रहे हैं। टाइप किए गए वर्गों को एक प्रतिनिधि की आवश्यकता हो सकती है जैसे [यह एक] (http://stackoverflow.com/a/43010363/538763)। – crokusek

+0

सही, विशिष्ट केवल अनाम प्रकार – imdadhusen

4

Distinct विधि अनुक्रम से अलग तत्व लौटाता है।

यदि आप प्रतिबिंबक के साथ इसके कार्यान्वयन पर एक नज़र डालें, तो आप देखेंगे कि यह आपके अज्ञात प्रकार के लिए DistinctIterator बनाता है। संग्रह पर गणना करते समय अलग इटरेटर Set पर तत्व जोड़ता है। यह गणक सभी तत्वों को छोड़ देता है जो पहले से ही Set में हैं।SetGetHashCode और Equals विधियों को परिभाषित करने के लिए उपयोग करता है यदि तत्व पहले से ही Set में मौजूद है या नहीं।

कैसे GetHashCode और Equals अज्ञात प्रकार के लिए लागू किया गया?

बराबर और अनाम प्रकार पर GetHashCode तरीकों के संदर्भ में परिभाषित कर रहे हैं बराबर है और संपत्तियों की GetHashcode तरीकों, दो उदाहरणों में एक ही गुमनाम प्रकार के की बराबर ही अगर अपने सभी गुण हैं कर रहे हैं: यह msdn पर कहा गया है बराबर।

तो, अलग-अलग संग्रह पर पुनरावृत्ति करते समय, आपके पास निश्चित रूप से अलग अज्ञात वस्तुएं होनी चाहिए। और परिणाम इस बात पर निर्भर नहीं है कि आप अपने अनाम प्रकार के लिए कितने फ़ील्ड का उपयोग करते हैं।

2

नीचे दिए गए अपने चयन कार्य में Key कीवर्ड का उपयोग करें।

product.Select(m => new {Key m.CategoryId, Key m.CategoryName}).Distinct();

मैं इस एक पुराने धागा ऊपर ला रहा है एहसास लेकिन सोचा यह कुछ लोगों को मदद कर सकता है। मैं आमतौर पर .NET के साथ काम करते समय VB.NET में कोड करता हूं ताकि Key अलग-अलग अनुवाद कर सकें #।

+0

VB.Net में एकाधिक फ़ील्ड पर एक अलग करने के लिए, किसी को अनाम प्रकार में प्रत्येक प्रॉपर्टी के लिए 'कुंजी' कीवर्ड का उपयोग करना होगा। (अन्यथा, तुलना के लिए उपयोग किए गए हैशकोड को उचित रूप से गणना नहीं की जाएगी) सी # में, कोई 'कुंजी' कीवर्ड नहीं है - इसके बजाय अनाम प्रकारों में सभी गुण स्वचालित रूप से मुख्य फ़ील्ड होते हैं। – voon

-2
Employee emp1 = new Employee() { ID = 1, Name = "Narendra1", Salary = 11111, Experience = 3, Age = 30 };Employee emp2 = new Employee() { ID = 2, Name = "Narendra2", Salary = 21111, Experience = 10, Age = 38 }; 
Employee emp3 = new Employee() { ID = 3, Name = "Narendra3", Salary = 31111, Experience = 4, Age = 33 }; 
Employee emp4 = new Employee() { ID = 3, Name = "Narendra4", Salary = 41111, Experience = 7, Age = 33 }; 

List<Employee> lstEmployee = new List<Employee>(); 

lstEmployee.Add(emp1); 
lstEmployee.Add(emp2); 
lstEmployee.Add(emp3); 
lstEmployee.Add(emp4); 

var eemmppss=lstEmployee.Select(cc=>new {cc.ID,cc.Age}).Distinct(); 
+3

यह उत्तर पहले से दिए गए उत्तरों में क्या जोड़ता है? –

+0

क्या होगा यदि मैं अब आयु द्वारा आदेश करना चाहता हूं? – Si8

0

सवाल (क्या लोगों को यहां आकर्षित) के शीर्षक का उत्तर देना और अनदेखी कि उदाहरण गुमनाम प्रकार इस्तेमाल किया ....

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

सहायक वर्ग:

/// <summary> 
/// Allow IEqualityComparer to be configured within a lambda expression. 
/// From https://stackoverflow.com/questions/98033/wrap-a-delegate-in-an-iequalitycomparer 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public class LambdaEqualityComparer<T> : IEqualityComparer<T> 
{ 
    readonly Func<T, T, bool> _comparer; 
    readonly Func<T, int> _hash; 

    /// <summary> 
    /// Simplest constructor, provide a conversion to string for type T to use as a comparison key (GetHashCode() and Equals(). 
    /// https://stackoverflow.com/questions/98033/wrap-a-delegate-in-an-iequalitycomparer, user "orip" 
    /// </summary> 
    /// <param name="toString"></param> 
    public LambdaEqualityComparer(Func<T, string> toString) 
     : this((t1, t2) => toString(t1) == toString(t2), t => toString(t).GetHashCode()) 
    { 
    } 

    /// <summary> 
    /// Constructor. Assumes T.GetHashCode() is accurate. 
    /// </summary> 
    /// <param name="comparer"></param> 
    public LambdaEqualityComparer(Func<T, T, bool> comparer) 
     : this(comparer, t => t.GetHashCode()) 
    { 
    } 

    /// <summary> 
    /// Constructor, provide a equality comparer and a hash. 
    /// </summary> 
    /// <param name="comparer"></param> 
    /// <param name="hash"></param> 
    public LambdaEqualityComparer(Func<T, T, bool> comparer, Func<T, int> hash) 
    { 
     _comparer = comparer; 
     _hash = hash; 
    } 

    public bool Equals(T x, T y) 
    { 
     return _comparer(x, y); 
    } 

    public int GetHashCode(T obj) 
    { 
     return _hash(obj); 
    }  
} 

सरल उपयोग:

List<Product> products = duplicatedProducts.Distinct(
    new LambdaEqualityComparer<Product>(p => 
     String.Format("{0}{1}{2}{3}", 
      p.ProductId, 
      p.ProductName, 
      p.CategoryId, 
      p.CategoryName)) 
     ).ToList(); 

सरल (लेकिन यह है कि कुशल नहीं) उपयोग इतना है कि कस्टम हैशिंग से बचा जाता है एक स्ट्रिंग प्रतिनिधित्व करने के लिए मैप करने के लिए है। समान तारों के पास पहले से ही हैश कोड हैं।

संदर्भ:
Wrap a delegate in an IEqualityComparer

0
public List<ItemCustom2> GetBrandListByCat(int id) 
    { 

     var OBJ = (from a in db.Items 
        join b in db.Brands on a.BrandId equals b.Id into abc1 
        where (a.ItemCategoryId == id) 
        from b in abc1.DefaultIfEmpty() 
        select new 
        { 
         ItemCategoryId = a.ItemCategoryId, 
         Brand_Name = b.Name, 
         Brand_Id = b.Id, 
         Brand_Pic = b.Pic, 

        }).Distinct(); 


     List<ItemCustom2> ob = new List<ItemCustom2>(); 
     foreach (var item in OBJ) 
     { 
      ItemCustom2 abc = new ItemCustom2(); 
      abc.CategoryId = item.ItemCategoryId; 
      abc.BrandId = item.Brand_Id; 
      abc.BrandName = item.Brand_Name; 
      abc.BrandPic = item.Brand_Pic; 
      ob.Add(abc); 
     } 
     return ob; 

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