在C#中使用LINQ Distinct
本文关键字:LINQ Distinct | 更新日期: 2023-09-27 18:26:31
我在LINQ中使用distinct
时遇到问题。我有这个清单:
LineIdChanged LineId OldGatewayPCId NewGatewayPCId LineStringID PlantID
1 93 83 88 160 2
2 93 83 88 161 2
3 94 82 87 162 2
4 94 82 87 163 2
我所尝试的是获得一个不同的LineId值,所以在这种情况下,我应该只获得两个对象,而不是所有四个对象。我试过这个:
var s = (from n in _dataBaseProvider.SelectPjdGatewayLineChanged(selectedSourcePlant.LPS_Database_ID)
select new PjdGatewayLineChanged() { LineId = n.LineId, LpsLineNo = n.LpsLineNo, LineIdChanged = n.LineIdChanged}).Distinct();
LinesOld = s.ToList();
但这给了我所有的4个对象。
您需要使用MoreLINQ的DistinctBy
:
var s =
(from n in _dataBaseProvider.SelectPjdGatewayLineChanged
(selectedSourcePlant.LPS_Database_ID)
select new PjdGatewayLineChanged
{
LineId = n.LineId,
LpsLineNo = n.LpsLineNo,
LineIdChanged = n.LineIdChanged
})
.DistinctBy(p => p.LineId);
您的问题是LINQ和.Net框架不知道如何区分PjdGatewayLineChanged
类型的不同对象。因此,它使用默认的方法,即在内存引用方面寻找相等性。
因此,您需要使用此方法的第二个重载,并提供IEqualityComparer
参见此处
Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)
以便LINQ知道如何比较PjdGatewayLineChanged
类型的不同实例
IEqualityComparer 的msdn链接
如果您认为所有行都相等,如果它们有一些字段相等:
var s = (from p in _dataBaseProvider.SelectPjdGatewayLineChanged(selectedSourcePlant.LPS_Database_ID)
select new PjdGatewayLineChanged()
{
LineId = p.LineId,
LpsLineNo = p.LpsLineNo,
LineIdChanged = p.LineIdChanged
})
.GroupBy(p => p.LineId)
.Select(p => p.First());
你按你的id分组,然后每组都排在第一行。
或者更紧凑的
var s = from p in _dataBaseProvider.SelectPjdGatewayLineChanged(selectedSourcePlant.LPS_Database_ID)
group p by p.LineId into q
let r = q.First()
select new PjdGatewayLineChanged()
{
LineId = r.LineId,
LpsLineNo = r.LpsLineNo,
LineIdChanged = r.LineIdChanged
};
通过这种方式,PjdGatewayLineChanged
的创建已移至最后一步(在选择groupby.
事情是这样的。Distinct(IEnumerable)方法返回一个不包含重复值的无序序列。它使用默认的相等比较器default来比较值。
有两个选项可以将.Distinct()
与您的自定义类型一起使用:
- 为
PjdGatewayLineChanged
提供您自己的GetHashCode和Equals方法 - 将重载的Distinct与自定义相等比较器一起使用
有关更多信息,请查看MSDN For Distinct查看MSDN For Distinct,您会发现很好的文档代码片段,这些代码片段将帮助您实现所需的功能。