2010-09-16 81 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());