2010-10-08 38 views
1

我将多个List汇总到一个List中,并希望根据Foo(Foo.Prop1)的某个属性使其不同。..我无权修改Foo的平等比较器。Linq查询问题:根据对象的属性不同

Dictionary<string, List<Foo>> fooDictionary = new Dictionary<string, List<Foo>>(); 
List<Foo> foovals = (from e in fooDictionary 
        where e.Key == "foo1" || e.Key == "foo2" || e.Key == "foo3" 
        select e.Value).SelectMany(f => f).ToList(); 

这里唯一缺少的是在最后的.Distinct(),使富独特的,但是,在我的情况,我不能修改关于富东西,所以简单的调用鲜明的()不会工作。

有没有办法修改这个查询返回项目Distinct基于Foo.Prop1?

回答

2

你可以在MoreLINQ使用DistinctBy方法:

var query = fooVals.DistinctBy(foo => foo.Property1); 
+0

不错!尽管这是CodeSmith模板的内部,所以不知道我是否可以添加语言扩展。 – 2010-10-08 22:42:00

3

您可以通过自定义相等比较器Distinct()

.SelectMany().Distinct(new FooEqualityComparer()); 

在一个新的文件, “FooEqualityComparer.cs”:

public class FooEqualityComparer : IEqualityComparer<Foo> 
{ 
    public bool Equals(Foo x, Foo y) 
    { 
     return Equals(x.Prop1, y.Prop1); 
    } 

    public int GetHashCode(Foo x) 
    { 
     return x.Prop1.GetHashCode(); 
    } 
} 
+0

也不能这样做..这是在一个codesmith模板中,而且Foo是由xml模式动态生成的,所以在代码模板中甚至不能访问..至少我知道如何.. – 2010-10-08 22:30:14

+0

您不需要需要访问类代码才能编写相等比较器... – codekaizen 2010-10-08 22:31:22

+0

我这样做,因为Foo是一个自定义类,并且相等比较器需要知道它需要比较它们的属性 – 2010-10-08 22:33:44

0
var tempKeys = new HashSet<int>(); // change int to the actual type of Prop1 

List<Foo> foovals = (from e in fooDictionary 
        where e.Key == "foo1" || e.Key == "foo2" || e.Key == "foo3" 
        select e.Value).SelectMany(f => f) 
            .Where(f => tempKeys.Add(f.Prop1)) 
            .ToList(); 
+0

太“聪明”,难以理解。哈克说:“哪里有副作用,你好。 – Timwi 2010-10-08 23:08:00

+0

@Timwi:这仅仅是一个概念证明,几乎就是'Distinct'本身在幕后做的事情。如Jon的回答中所提到的那样,将其包含在一个通用扩展方法中,该方法也接受一个按键选择器函数,并且您刚刚重写了'DistinctBy'。 – LukeH 2010-10-08 23:19:58