4

distinct在 LINQ 中使用时遇到问题。我有这个清单:

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 个对象。

4

4 回答 4

3

您需要使用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);
于 2013-08-05T11:45:41.643 回答
0

你的问题是 LINQ 和 .Net 框架知道如何区分不同类型的对象PjdGatewayLineChanged。所以它使用默认的东西,即在内存引用方面寻找相等性。

所以你需要做的是使用这个方法的第二个重载并提供一个IEqualityComparer

看这里

Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)

以便 LINQ 知道如何比较IEqualityComparer的PjdGatewayLineChanged
msdn链接类型的差异实例

于 2013-08-05T11:48:05.090 回答
0

如果您认为所有行在某些字段相等的情况下都相等:

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 的正确“候选人”之后。

于 2013-08-05T11:51:56.180 回答
0

事情就是这样。Distinct(IEnumerable) 方法返回不包含重复值的无序序列。它使用默认的相等比较器Default来比较值。

有两个选项可用于.Distinct()您的自定义类型:

  1. PjdGatewayLineChanged.
  2. 将重载的 Distinct 与您的自定义平等比较器一起使用

有关详细信息,请查看 MSDN for Distinct,查看 MSDN for Distinct,您会找到很好的文档代码片段,它们将帮助您实现所需的功能。

于 2013-08-05T12:04:39.870 回答