2012-06-29 81 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

你很不走运,这对我很好 –