2012-06-29 80 views
-1

我嘗試的LINQ to刪除重複項:獨特不會刪除重複項目?

var MyItems = (from b in this.result 
       select new Item{ Name = b.Name, ID = b.ID }).Distinct(); 

的我檢查的結果,它不會刪除重複的項目。 如何解決這個問題?

+2

通過標準重複?你是否在'Item'中覆蓋了'Equals'? – Tudor

+2

在此上下文中定義「重複」 - 相同的ID?您可能必須提供一個相等比較器。 –

+0

謝謝,夥計們。在覆蓋Equals和GetHashCode之後立即開始工作。 – KentZhou

回答

1

常規Distinct()通過使用默認的相等比較器從集合中返回元素。

可以使用自定義comparer此:

// modified example from docs, not tested 
class MyComparer : IEqualityComparer<Item> 
{ 
    // Items are equal if their ids are equal. 
    public bool Equals(Item x, Item y) 
    { 

     // Check whether the compared objects reference the same data. 
     if (Object.ReferenceEquals(x, y)) return true; 

     // Check whether any of the compared objects is null. 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
      return false; 

     //Check whether the items properties are equal. 
     return x.ID == y.ID; 
    } 

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects. 

    public int GetHashCode(Product product) 
    { 
     //Check whether the object is null 
     if (Object.ReferenceEquals(item, null)) return 0; 

     //Get hash code for the ID field. 
     int hashProductId = product.ID.GetHashCode(); 

     return hashProductId; 
    } 

} 

var myItems = (from b in this.result 
       select new Item{ Name = b.Name, ID = b.ID }).Distinct(new MyComparer()); 
4

默認情況下,Distinct()使用EqualityComparer<T>.Default,它具有以下規則:

默認的相等比較,默認情況下,用於比較實現IEquatable通用接口的類型的值。要比較自定義數據類型,您需要實現此接口併爲該類型提供您自己的GetHashCode和Equals方法。

對你而言,這意味着Item需要執行IEquatable<Item>

或者,您可以使用overload of Distinct,它直接採用IEqualityComparer<T>

1

因爲我不知道你在這之後如何使用Items,所以我在這裏賭博。

如果真的只需要的ID名稱對,您可以使用匿名類型,並獲得免費的比較:

var MyItems = (from b in this.result 
       select new { b.Name, b.ID }).Distinct(); 

在此之後(再一次假設所有你需要的是名稱,ID對),得到的對象將有屬性,你需要:

foreach(var item in MyItems) 
    Console.WriteLine("{0} -> {1}", item.ID, item.Name); 

C# Anonymous Types引用MSDN:

因爲匿名類型上的Equals和GetHashCode方法是根據屬性的Equals和GetHashcode方法定義的,所以只有當它們的所有屬性相同時,相同匿名類型的兩個實例才相等。

2

您可以通過鮮明的()一個比較器對象:

var MyItems = (from b in this.result 
      select new Item{ Name = b.Name, ID = b.ID }).Distinct(new ItemComparer()); 

這裏是自定義比較類

// Custom comparer for the Item class 
class ItemComparer: IEqualityComparer<Product> 
{ 
    // Items are equal if their names and IDs are equal. 
    public bool Equals(Item x, Item y) 
    { 

     //Check whether the compared objects reference the same data. 
     if (Object.ReferenceEquals(x, y)) return true; 

     //Check whether any of the compared objects is null. 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
      return false; 

    //Check whether the items' properties are equal. 
    return x.ID == y.ID && x.Name == y.Name; 
    } 

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects. 

    public int GetHashCode(Item item) 
    { 
     //Check whether the object is null 
     if (Object.ReferenceEquals(item, null)) return 0; 

     //Get hash code for the Name field if it is not null. 
     int hashItemName = item.Name == null ? 0 : item.Name.GetHashCode(); 

     //Get hash code for the ID field. 
     int hashItemID = item.ID.GetHashCode(); 

     //Calculate the hash code for the item. 
     return hashItemName^hashItemID; 
    } 

} 
-4

您需要添加新的項目列表,使用的foreach考試的例子:

foreach(var _item in result.Distinct()){ 
//Code here 
} 

ok :)

+0

不好::(........ –

+0

你很不走運,這對我很好 –