此代码返回不同的值。 但是,我想要的是返回强类型集合而不是匿名类型
我有以下代码:
var foo = (from data in pivotedData.AsEnumerable() select new { Group = data.Field("Group_Number"), Study = data.Field("Study_Name") }).Distinct();
正如预期的那样,这将返回不同 但是,我想要的是返回强类型集合而不是匿名类型,所以当我这样做时:
var foo = (from data in pivotedData.AsEnumerable() select new BarObject { Group = data.Field("Group_Number"), Study = data.Field("Study_Name") }).Distinct();
这不会返回不同的值,它会返回所有值。 有没有办法用实际对象做到这一点?
要使Distinct()
(和许多其他LINQfunction)工作,要比较的类(在您的示例中为BarObject
)必须实现实现Equals()
和GetHashCode()
,或者另外提供单独的IEqualityComparer
作为Distinct()
的参数Distinct()
。
许多LINQ方法利用GetHashCode()
来提高性能,因为在内部它们将使用诸如Set
类的东西来保存唯一项,这些项使用散列进行O(1)查找。 此外, GetHashCode()
可以快速告诉您两个对象是否可能是等效的,哪些绝对不是 – 只要GetHashCode()
当然正确实现。
因此,为了完整性,您应该在LINQ实现Equals()
和GetHashCode()
中创建要比较的所有类,或者创建单独的IEqualityComparer
实现。
要么像dlev建议或使用:
var foo = (from data in pivotedData.AsEnumerable() select new BarObject { Group = data.Field("Group_Number"), Study = data.Field ("Study_Name") }).GroupBy(x=>x.Group).Select(x=>x.FirstOrDefault())
查看更多信息http://blog.jordanterrell.com/post/LINQ-Distinct()-does-not-work-as-expected.aspx
您需要为BarObject
重写Equals
和GetHashCode
,因为EqualityComparer.Default
是引用相等,除非您提供了Equals
和GetHashCode
覆盖(这是Enumerable.Distinct
使用的)。 或者,您可以将IEqualityComparer
传递给Enumerable.Distinct
。
看起来Distinct
无法比较您的BarObject
对象。 因此,它比较了它们的引用,它们当然彼此不同,即使它们具有相同的内容。
因此要么覆盖Equals
方法,要么为Distinct
提供自定义EqualityComparer。 记住在实现Equals
时覆盖GetHashCode
,否则如果将对象放入字典或哈希表作为键(例如HashSet
),它将产生奇怪的结果。 它可能(不确切地知道)Distinct内部使用哈希集。
以下是GetHashCode
的一系列良好实践。
你想使用带有比较器的Distinct()的另一个重载 。 然后,您可以实现自己的IEqualityComparer
试试这个:
var foo = (from data in pivotedData.AsEnumerable().Distinct() select new BarObject { Group = data.Field("Group_Number"), Study = data.Field ("Study_Name") });
应该如此简单:
var foo = (from data in pivotedData.AsEnumerable() select new { Group = data.Field("Group_Number"), Study = data.Field ("Study_Name") }).Distinct().Select(x => new BarObject { Group = x.Group, Study = x.Study });