Linq连接将对象与子对象列表进行比较

时间:2014-03-26 21:14:01

标签: c# compare linq-to-objects

我需要比较两个对象列表。此对象再次具有其他对象的列表。我需要加入。

public class MaterialXML
{
    public string Reference {get;set;}
    public string MeasurementUnitCode {get;set;}
    public IEnumerable<AlternateUnitXML> AlternateUnits { get; set; }
}

public class AlternateUnitXML
{
    public string Code { get; set; }
    public decimal PrimaryQuantity{get;set;}
    public decimal SecondaryQuantity{get; set;}

}

通过这个课程我通常会这样比较: 我将在没有MaterialXML对象的IEnumerable的情况下解释它。

IEnumerable<MaterialXML> matListA=repository.getMatA();
IEnumerable<MaterialXML> matListB=repository.getMatB();

//For get the objects in a that are similar in b:

IEnumerable<MaterialXML> matOnASimilarToB= from p in matListA
                                           join h in matListB on 
                                           new{ p.Reference , 
                                                p.MeasurementUnitCode
                                              }
                                           equals
                                           new{ h.Reference , 
                                                h.MeasurementUnitCode
                                              }
                                           select p;

我的问题是,如果我尝试将材质xml与相同的引用,measurementunitcode和相同的AlternateUnitCode列表进行比较。

有可能吗?

例如:

  1. 列表A:

    1. 参考= MatA1 MeasurerementUnitCode = T AlternateUnits:
        1. 代码:A PrimaryQuantity:1 SecundaryQuantity:2
        1. 代码:B PrimaryQuantity:1 SecundaryQuantity:3
        1. 代码:C PrimaryQuantity:1 SecundaryQuantity:4
    2. 参考= MatA2 MeasurerementUnitCode = T AlternateUnits:
        1. 代码:A PrimaryQuantity:1 SecundaryQuantity:12
        1. 代码:B PrimaryQuantity:1 SecundaryQuantity:13
        1. 代码:C PrimaryQuantity:1 SecundaryQuantity:14
    3. 参考= MatA3 MeasurerementUnitCode = T AlternateUnits:
        1. 代码:A PrimaryQuantity:1 SecundaryQuantity:12
        1. 代码:B PrimaryQuantity:1 SecundaryQuantity:13
        1. 代码:C PrimaryQuantity:1 SecundaryQuantity:14
        1. 代码:D PrimaryQuantity:1 SecundaryQuantity:15
  2. 列表B:

    1. 参考= MatA1 MeasurerementUnitCode = T AlternateUnits:
        1. 代码:A PrimaryQuantity:1 SecundaryQuantity:2
        1. 代码:B PrimaryQuantity:1 SecundaryQuantity:3
        1. 代码:C PrimaryQuantity:1 SecundaryQuantity:4
    2. 参考= MatA2 MeasurerementUnitCode = T AlternateUnits:
        1. 代码:A PrimaryQuantity:1 SecundaryQuantity:12
        1. 代码:B PrimaryQuantity:1 SecundaryQuantity:13
        1. 代码:C PrimaryQuantity:1 SecundaryQuantity:74
    3. 参考= MatA3 MeasurerementUnitCode = T AlternateUnits:
        1. 代码:A PrimaryQuantity:1 SecundaryQuantity:12
        1. 代码:B PrimaryQuantity:1 SecundaryQuantity:13
        1. 代码:C PrimaryQuantity:1 SecundaryQuantity:14
  3. 在数组a y b中的数据的示例中,只有de MatA1是相同的。 matA2是不同的,因为备用单元C在一个壳体14中具有并且在第二壳体78中具有备用单元C. matA3是不同的,因为在一种情况下有3个备用单元,而在另一种情况下有4个。

2 个答案:

答案 0 :(得分:0)

您需要从一些自定义比较器开始,以自定义连接执行匹配的方式:

    public class MaterialXMLComparer : IEqualityComparer<MaterialXML>
    {
        private  IEqualityComparer<AlternateUnitXML> _alternateComparer;
        public MaterialXMLComparer(IEqualityComparer<AlternateUnitXML> alternateComparer)
        {
            _alternateComparer = alternateComparer;
        }
        public bool Equals(MaterialXML x, MaterialXML y)
        {
            bool firstLevelEqual = (x.Reference == y.Reference) &&
                (x.MeasurementUnitCode == y.MeasurementUnitCode);

            if (firstLevelEqual)
            {
                if (x.AlternateUnits.SequenceEqual(y.AlternateUnits, _alternateComparer))
                {
                    return true;
                }
            }

            return false;
        }
        public int GetHashCode(MaterialXML obj)
        {
            return obj.Reference.GetHashCode();
        }
    }
    public class AlternateUnitXMLComparer : IEqualityComparer<AlternateUnitXML>
    {

        public bool Equals(AlternateUnitXML x, AlternateUnitXML y)
        {
            return (x.Code == y.Code) &&
                (x.PrimaryQuantity == y.PrimaryQuantity) &&
                (x.SecondaryQuantity == y.SecondaryQuantity);
        }

        public int GetHashCode(AlternateUnitXML obj)
        {
            return obj.Code.GetHashCode();
        }
    }

然后,您可以直接使用Join方法添加自定义比较器:

        var joinedList = matListA.Join(matListB,
            x => x,
            y => y,
            (x, y) => x,
            new MaterialXMLComparer(new AlternateUnitXMLComparer()));

joinedList现在只包含matListA中与matListB匹配的条目的条目。

答案 1 :(得分:0)

很完美。

我使用该代码并正确比较对象。

真的,我在实体中还有一个字段

public class MaterialXMLComparer : IEqualityComparer<MaterialXML>
    {
        private IEqualityComparer<AlternateUnitXML> _alternateComparer;
        private IEqualityComparer<MaterialsPatnerXMLforMaterial> _matPartnerComparer;

        public MaterialXMLComparer(IEqualityComparer<AlternateUnitXML> alternateComparer,IEqualityComparer<MaterialsPatnerXMLforMaterial> matPartnerComparer)
        {
            _alternateComparer = alternateComparer;
            _matPartnerComparer = matPartnerComparer;
        }
        public bool Equals(MaterialXML x, MaterialXML y)
        {
            bool firstLevelEqual = (x.Reference == y.Reference) &&
                    (x.MeasurementUnitCode == y.MeasurementUnitCode) &&
                    (x.Denomination == y.Denomination) &&
                    (x.Weight == y.Weight) &&
                    (x.PieceType == y.PieceType) &&
                    (x.Type == y.Type) &&
                    (x.Position == y.Position);

            bool secondLevelEqual=false;
            if (firstLevelEqual)
            {
                if (x.AlternateUnits.SequenceEqual(y.AlternateUnits, _alternateComparer))
                {
                    secondLevelEqual= true;
                }
            }

            if (secondLevelEqual)
            {
                if (x.MaterialsPartner.SequenceEqual(y.MaterialsPartner, _matPartnerComparer))
                {
                    return true;
                }
            }

            return false;
        }
        public int GetHashCode(MaterialXML obj)
        {
            return obj.Reference.GetHashCode();
        }
    }

感谢。