2011-11-18 75 views
1

我有一个过滤器列表传递到一个web服务,我迭代集合并做Linq查询,然后添加到产品列表,但当我做一个GroupByDistinct()它不会删除重复项。我正在使用IEnumerable,因为当您使用Disinct时,它会将其转换为IEnumerable。如果你知道如何更好地构造这个函数,并且使我的函数返回一个List<Product>类型,我将不胜感激。不同的()返回列表<>返回重复

这是我在C#代码:

if (Tab == "All-Items") 
{ 
    List<Product> temp = new List<Product>(); 
    List<Product> Products2 = new List<Product>(); 
    foreach (Filter filter in Filters) 
    {       
     List<Product> products = (from p in db.Products where p.Discontinued == false 
            && p.DepartmentId == qDepartment.Id 
            join f in db.Filters on p.Id equals f.ProductId 
            join x in db.ProductImages on p.Id equals x.ProductId 
            where x.Dimension == "180X180" 
            && f.Name == filter.Name /*Filter*/ 
            select new Product 
            { 
             Id = p.Id, 
             Title = p.Title, 
             ShortDescription = p.ShortDescription, 
             Brand = p.Brand, 
             Model = p.Model, 
             Image = x.Path, 
             FriendlyUrl = p.FriendlyUrl, 
             SellPrice = p.SellPrice, 
             DiscountPercentage = p.DiscountPercentage, 
             Votes = p.Votes, 
             TotalRating = p.TotalRating 
            }).ToList<Product>(); 

     foreach (Product p in products) 
     { 
      temp.Add(p); 
     }       

     IEnumerable temp2 = temp.GroupBy(x => x.Id).Distinct(); 
     IEnumerator e = temp.GetEnumerator(); 
     while (e.MoveNext()) { 
      Product c = e.Current as Product; 
      Products2.Add(c); 
     } 
    } 
    pf.Products = Products2;// return type must be List<Product>     
} 
+0

我发现你在代码的早些时候使用了ToList - 你也可以在你的返回值上使用它。 – sq33G

回答

3

你分配GroupBy结果temp2,但你从来没有使用它!

IEnumerable temp2 = temp.GroupBy(x => x.Id).Distinct();   
IEnumerator e = temp.GetEnumerator(); // <- why temp and not temp2??? 

但是你根本没有真正使用GroupBy操作符。您需要进行分组,然后从每个组中选择一个项目,而不是选择不同的组。这些组是已经不同

当组由ID,您实际上会返回一个结构类似这样的

-Key: 1 
    -Product (Id = 1) 
-Key: 2 
    -Product (Id = 2) 
    -Product (Id = 2) 

你需要从每个组检索项目。假设重复项,你不会在乎你得到哪个项目,所以你可以从每个组中获取第一项。

var groups = temp.GroupBy(x => x.Id); 
var distinctItems = groups.Select(g => g.First()); 

foreach (var item in distinctItems) 
{ 
    // do stuff with item 
    Products2.Add(item); 
} 
+0

...为什么你仍然在调用Distinct? – sq33G

+0

@ sq33G很好的皮卡;)纯粹是因为我剪切并粘贴了原始代码并忘记删除它。现在修复。 –

+0

我试过你的例子,它没有工作,这部分在这里Product c = e.Current as Product;在上下文中不存在任何其他建议 – ONYX

4

你需要重写EqualsGetHashCode按值来比较Product秒。

+0

我从来没有做过重写HasCodes你可以做它或给一个例子做什么。 – ONYX

+0

http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx – SLaks

+0

http://stackoverflow.com/questions/263400/what-is - 最好的算法 - 重写 - 系统对象 - gethashcode – SLaks

0

SLaks是正确的,您必须重写Equals()和GetHashCode()方法来完成此操作。

这是我在我写的小程序中的一个Order对象内做到的。希望这可以帮助!

//overridden Equals() method from the Object class, determines equality based on order number 
    public override bool Equals(object obj) 
    { 
     bool equal; 
     if (this.GetType() != obj.GetType()) 
      equal = false; 
     else 
     { 
      Order temp = (Order)obj; 
      if(OrderNumber == temp.OrderNumber) 
       equal = true; 
      else 
       equal = false; 
     } 
     return equal; 
    } 

    //overridden GetHashCode() method from Object class, sets the unquie identifier to OrderNumber 
    public override int GetHashCode() 
    { 
     return OrderNumber; 
    } 
+0

当你说对象类是我的类产品或我的web服务时,我很困惑把它放在哪里 – ONYX

+0

和我需要改变我的代码,我提供可以更新我提供的 – ONYX

+0

你想在你的产品类,因为这是你试图比较。 – jmshapland