linq查询groupby未能将所有具有相似键的行分组

本文关键字:相似 linq groupby 查询 | 更新日期: 2024-05-15 23:07:58

这是我的查询:

rows.GroupBy(row => new TaxGroupObject
            {
                EnvelopeID = row.Field<int>("EnvelopeID"),
                PolicyNumber = row.Field<string>("PolicyNumber"),
                TZ = row.Field<string>("TZ")
            })
            .Select(row =>
                        {
                            int i;
                            if (row.Key.EnvelopeID == 5713 && row.Key.PolicyNumber == "50002617" && row.Key.TZ == "50002617") 
                                i=1+1;
                            var newRow = structure.NewRow();
                            newRow["PolicyNumber"]=row.Key.PolicyNumber;
                            newRow["TZ"]=row.Key.TZ;
                            newRow["CreditPremiaTaxParagraph45"] = row.Sum(x => decimal.Parse(x["CreditPremiaTaxParagraph45"].ToString()));
                            newRow["WorklossTax"] = row.Sum(x => decimal.Parse(x["WorklossTax"].ToString()));
                            newRow["MiscTax"] = row.Sum(x => decimal.Parse(x["MiscTax"].ToString()));
                            newRow["EnvelopeID"] = row.Key.EnvelopeID;
                            return newRow;
                        }
            );
    internal class TaxGroupObject
{
    public long? EnvelopeID{ get; set; }
    public string PolicyNumber { get; set; }
    public string TZ { get; set; }
}

我在"i=1+1"行上放了一个断点,在if条件之后,将我为该组使用的所有键与一些硬编码值进行比较。该断点被击中两次,尽管该组假设将具有相同键的所有行分组在一起。问题是,对于表中的大多数值,分组工作得很好,我不明白这是怎么可能的。如果你能以任何方式提供帮助,我们将不胜感激。

linq查询groupby未能将所有具有相似键的行分组

问题是TaxGroupObject没有实现GetHashCodeEqualsGroupBy使用这些方法来确定是什么使一个TaxGroupObject对象与另一个对象相等。默认情况下,它是通过引用相等,而不是属性相等。

这应该可以工作,使用来自What is the best algorithm for a overrided System.Object.GetHashCode?的GetHashCode算法:

internal class TaxGroupObject
{
    public long? EnvelopeID { get; set; }
    public string PolicyNumber { get; set; }
    public string TZ { get; set; }
    public override int GetHashCode()
    {
        unchecked // Overflow is fine, just wrap
        {
            int hash = 17;
            hash = hash * 23 + EnvelopeID.GetHashCode();
            hash = hash * 23 + (PolicyNumber != null ? PolicyNumber.GetHashCode() : -2);
            hash = hash * 23 + (TZ != null ? TZ.GetHashCode() : -1);
            return hash;
        }
    }
    public override bool Equals(object obj)
    {
        if (obj.GetType() != typeof(TaxGroupObject))
            return false;
        var other = (TaxGroupObject)obj;
        return this.EnvelopeID == other.EnvelopeID &&
                this.PolicyNumber == other.PolicyNumber &&
                this.TZ == other.TZ;
    }
}

此外,您应该只在分组或字典中使用不可变对象。至少,您必须确保此处的对象在分组过程中不会发生更改。

最终我发现放弃继承并使用结构而不是类更简单,它也能工作,因为结构是一种值类型,因此不需要equals方法重写。如果有人知道的话,我很好奇这些方法中的哪一种能带来更好的性能。从直觉上看,structs似乎更高效,但我不确定,而且我目前没有时间模仿这两个选项或进行适当的重新(谷歌)搜索
感谢