[英]Using LINQ Distinct in C#
I have an issue using distinct
in LINQ. 我在LINQ中使用distinct
有一个问题。 I have this list: 我有这个清单:
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
What I have tried is to get a distinct LineId value, so in this case I should only get two objects instead of all four objects. 我试过的是获得一个不同的LineId值,所以在这种情况下我应该只获得两个对象而不是所有四个对象。 I have tried this: 我试过这个:
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();
But this gives me all 4 objects. 但这给了我所有4个对象。
You need to use MoreLINQ's DistinctBy
: 你需要使用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);
what your problem is that the LINQ and the .Net framework dosent know how to differentiate betwwen different objects of type PjdGatewayLineChanged
. 您的问题是LINQ和.Net框架知道如何区分PjdGatewayLineChanged
类型的不同对象。 so it uses the default thing which is to look for equality in the terms of memory reference. 所以它使用默认的东西来寻找内存引用方面的相等性。
So what you need to do instead is use the second overload of this method and provide an IEqualityComparer
所以你需要做的是使用这个方法的第二个重载并提供IEqualityComparer
Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)
so that LINQ known how to compare diff instances of type PjdGatewayLineChanged
这样LINQ知道如何比较PjdGatewayLineChanged
类型的diff实例
msdn link of IEqualityComparer IEqualityComparer的msdn 链接
If you consider all the rows to be equal if they have some fields equal: 如果你认为所有行都相等,如果它们有一些相等的字段:
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());
You group-by by your id and then for each group take the first row. 您按ID分组,然后为每个组分组取第一行。
or, more compact, 或者,更紧凑,
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
};
In this way the creation of PjdGatewayLineChanged
has been moved to the last step (after the selection of the right "candidate" of the groupby. 通过这种方式, PjdGatewayLineChanged
的创建已经移动到最后一步(在选择了groupby的右“候选者”之后)。
Here is the thing. 这就是事情。 The Distinct(IEnumerable) method returns an unordered sequence that contains no duplicate values. Distinct(IEnumerable)方法返回一个不包含重复值的无序序列。 It uses the default equality comparer, Default , to compare values. 它使用默认的相等比较器Default来比较值。
There are two options to use .Distinct()
with your custom types: 有两个选项可以使用.Distinct()
和您的自定义类型:
PjdGatewayLineChanged
. 为PjdGatewayLineChanged
提供自己的GetHashCode和Equals方法。 For more info check MSDN for Distinct check MSDN for Distinct, you'll find good documentation code snippets which will help you implement needed functionality. 有关更多信息, 请查看MSDN for Distinct检查MSDN for Distinct,您将找到可帮助您实现所需功能的良好文档代码片段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.