2010-09-16 82 views
4

當我使用下面的代碼時,我多次獲得相同的項目。使用LINQ選擇唯一項目

XElement neededFiles = new XElement("needed", 
    from o in _9nFiles.Elements() 
    join t in addedToSitePull.Elements() 
     on o.Value equals 
     t.Value 
    where o.Value == t.Value 
    select new XElement("pic", o.Value)); 

我想只得到獨特的項目。我看到堆棧溢出帖子,How can I do SELECT UNIQUE with LINQ?,使用它,我試圖實現它,但改變沒有影響。

代碼:

XElement neededFiles = new XElement("needed", 
(from o in _9nFiles.Elements() 
join t in addedToSitePull.Elements() 
on o.Value equals 
t.Value 
where o.Value == t.Value 
select new XElement("pic", o.Value)).Distinct()); 

回答

7

我想這不工作的原因是因爲XElement.Equals使用一個簡單的參考平等檢查,而不是比較兩個項目的Value性能。如果要比較的值,你可以將其更改爲:

_9nfiles.Elements() 
    .Join(addedToSitePull, o => o.Value, t => t.Value, (o, t) => o.Value) 
    .Distinct() 
    .Select(val => new XElement("pic", val)); 

你也可以通過他們的價值觀比較兩個XElement S創建你自己的IEqualityComparer<T>。注意這是假定所有的值都是非空:

public class XElementValueEqualityComparer : IEqualityComparer<XElement> 
{ 
    public bool Equals(XElement x, XElement y) 
    { 
     return x.Value.Equals(y.Value); 
    } 

    public int GetHashCode(XElement x) 
    { 
     return x.Value.GetHashCode(); 
    } 
} 

然後,你可以用Distinct(new XElementValueEqualityComparer())取代現有的呼叫Distinct

+0

+1儘管我不得不實施一個不好解決由於時間問題,我期待着測試和了解您的解決方案 - 感謝阿薩夫 – Asaf 2010-09-16 15:22:29

4

區別不起作用,因爲XElements通過引用進行比較,而不是按值進行比較。 解決方法是使用Distinct - Distinct(IEqualityComparer)的另一個重載;

你需要實現的IEqualityComparer舉例如下:

class XElementEqualityComparer : IEqualityComparer<XElement> 
    { 
     #region IEqualityComparer<XElement> Members 

     public bool Equals(XElement x, XElement y) 
     { 
      if (x == null^y == null) 
       return false; 

      if (x == null && y == null) 
       return true; 

      return x.Value == y.Value; 
     } 

     public int GetHashCode(XElement obj) 
     { 
      if (obj == null) 
       return 0; 

      return obj.Value.GetHashCode(); 
     } 

     #endregion 
    } 
+1

李的回答是更好,因爲它更緊湊。我離開我的只是例如 – ILya 2010-09-16 10:09:39

+0

+1感謝您的不負責任的使用其他解決方案的罕見建議。 – Asaf 2010-09-16 15:12:37

0

這不是一個很好的解決方案 - 但真的很容易。

foreach (XElement pic in neededFiles.Elements()) 
{ 
    unSyncedPictures.Add(pic.Value); 
} 
List<string> temp = new List<string>(); 
temp.AddRange(unSyncedPictures.Distinct());