我想寫一個複雜類型的集合的LINQ查詢。我想在兩個字段的組合上爲這個集合寫一個獨特的查詢。C#LINQ Distinct(f => f.propertyname)does not work
我不認爲Lambda表達式支持Distinct(f => f.propertyname)的管道。希望它做到了。任何人使用簡單的實現,然後使用比較器?
我想寫一個複雜類型的集合的LINQ查詢。我想在兩個字段的組合上爲這個集合寫一個獨特的查詢。C#LINQ Distinct(f => f.propertyname)does not work
我不認爲Lambda表達式支持Distinct(f => f.propertyname)的管道。希望它做到了。任何人使用簡單的實現,然後使用比較器?
你不能使用這樣的獨特。編譯器無法知道要採用多個值中的哪一個。您可以使用GroupBy()來合併它們,或者根據需要使用Min(),Max(),First(),Last()或類似的方法從列表中選擇一個。
您有幾種選擇:
IEqualityComparer<T>
爲Distinct
Equals
+ GethashCode
另一個(低效率)不需要創建新類或修改現有的方法是使用內建的GetHashCode
+ Equals
匿名類型和Enumerable.GroupBy
:
IEnumerable<Complex> distinctObjects =
from c in collection
group c by new { c.Prop1, c.Prop2 } into g
select g.First(); // change logic if you don't want an arbitrary object(first)
這裏的第二種方法的一個例子:
public class Complex
{
public string Prop1 { get; set; }
public int Prop2 { get; set; }
public Complex Prop3 { get; set; }
public override bool Equals(object obj)
{
Complex c2 = obj as Complex;
if (obj == null) return false;
return Prop1 == c2.Prop1 && Prop2 == c2.Prop2;
}
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + Prop1.GetHashCode();
hash = hash * 23 + Prop2;
return hash;
}
}
}
的Equals
和IEqualityComparer
-class(1 GethashCode
。方法)會類似。
純LINQ,你可以通過你所需要的所有屬性,然後從組每組中選擇第一項:
var result = items.GroupBy(i => new { i.Prop1, i.Prop2 })
.Select(g => g.First());
優點:
缺點在服務器端執行:
你可以用你的T動態創建一個匿名類型wo屬性,然後使用不同的。
像這樣:
[Test]
public void Distinct_with_anonymous_type()
{
var items = new[]
{
new {p1 = 'a', p2 = 2, p3=10}, // double over p1 and p2
new {p1 = 'a', p2 = 3, p3=11},
new {p1 = 'a', p2 = 2, p3=12}, // double over p1 and p2
};
var expected = new[]
{
new {p1 = 'a', p2 = 2},
new {p1 = 'a', p2 = 3},
};
var distinct = items.Select(itm => new { itm.p1, itm.p2 }).Distinct();
Assert.That(distinct, Is.EquivalentTo(expected));
}
希望這有助於!
你能發佈你的完整查詢嗎? – Dutts
它被[MoreLINQ](https://www.nuget.org/packages/morelinq/1.0.16006)包含爲['DistinctBy',以下是示例源代碼](https://code.google.com/p/ morelinq/source/browse/MoreLinq/DistinctBy.cs) –