繁体   English   中英

在C#中使用LINQ Distinct

[英]Using LINQ Distinct in C#

我在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类型的diff实例
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()和您的自定义类型:

  1. PjdGatewayLineChanged提供自己的GetHashCode和Equals方法。
  2. 使用重载区别于您的自定义Equality Comparer

有关更多信息, 请查看MSDN for Distinct检查MSDN for Distinct,您将找到可帮助您实现所需功能的良好文档代码片段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM