在C#中使用LINQ的Distinct方法

11 浏览
0 Comments

在C#中使用LINQ的Distinct方法

我在使用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个对象。

0
0 Comments

问题的原因是需要从数据库中选择一组数据,并根据其中的某些字段进行分组。然后,对于每个分组,需要选择其中的第一行作为代表。

解决方法是使用LINQ中的Distinct方法。首先,使用Select语句从数据库提供程序中选择所需的数据,并创建PjdGatewayLineChanged对象。然后,使用GroupBy方法将数据按照LineId字段进行分组。最后,使用Select方法选择每个分组中的第一行作为代表。

以下是使用Distinct方法的示例代码:

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());

另一种更简洁的写法是:

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对象的过程被移动到了最后一步,即在选择分组中的合适的"候选者"之后。

0
0 Comments

问题出现的原因是LINQ和.NET框架不知道如何区分类型为PjdGatewayLineChanged的不同对象。默认情况下,它们会根据内存引用来判断相等性。解决方法是使用Distinct方法的第二个重载,并提供一个实现了IEqualityComparer接口的对象。这样LINQ就能够比较不同的PjdGatewayLineChanged实例了。

以下是使用Distinct方法的第二个重载的示例代码:

public class PjdGatewayLineChangedEqualityComparer : IEqualityComparer
{
    public bool Equals(PjdGatewayLineChanged x, PjdGatewayLineChanged y)
    {
        // Implement your comparison logic here
        return x.Id == y.Id; // Example: Compare by Id property
    }
    public int GetHashCode(PjdGatewayLineChanged obj)
    {
        // Implement your hash code generation logic here
        return obj.Id.GetHashCode(); // Example: Use Id property for hash code
    }
}
// Usage
IEnumerable distinctItems = items.Distinct(new PjdGatewayLineChangedEqualityComparer());

使用上述代码,我们创建了一个实现了IEqualityComparer接口的PjdGatewayLineChangedEqualityComparer类。在Equals方法中,我们可以根据自己的比较逻辑来判断两个对象是否相等。在GetHashCode方法中,我们可以根据自己的需求生成哈希码。然后,我们可以通过传递这个自定义的比较器对象给Distinct方法来获取不重复的PjdGatewayLineChanged对象的集合。

更多关于IEqualityComparer接口的信息可以参考MSDN文档:[链接](http://msdn.microsoft.com/en-us/library/ms132151.aspx)

0
0 Comments

使用LINQ Distinct的原因是需要从数据源中筛选出唯一的元素。然而,使用LINQ的Distinct方法只能对整个对象进行比较,而不能对特定属性进行比较。在上述示例中,需要根据LineId属性来筛选出唯一的元素。

解决方法是使用MoreLINQ库中的DistinctBy方法。DistinctBy方法允许根据指定的属性来筛选唯一的元素。在上述示例中,使用DistinctBy(p => p.LineId)来根据LineId属性来筛选唯一的元素。

另一种解决方法是使用GroupBy方法进行分组,然后再使用Select方法选择每组中的第一个元素。这种方法与MoreLINQ库中DistinctBy方法的实现类似,只是在某些平台上使用了Hashset来实现而已。

如果不想引入整个MoreLINQ库,可以直接使用DistinctBy方法的实现。可以在MoreLINQ库的源代码中找到DistinctBy方法的实现,并将其直接使用在项目中(记得注明来源)。

使用LINQ Distinct方法时,如果需要根据特定属性来筛选唯一的元素,可以使用MoreLINQ库中的DistinctBy方法或者使用GroupBy和Select方法的组合来实现。如果不想引入整个MoreLINQ库,可以直接使用DistinctBy方法的实现。

0