如何使用具有不同类的多个属性的linq`Except`? [英] How to use linq `Except` with multiple properties with different class?

查看:83
本文介绍了如何使用具有不同类的多个属性的linq`Except`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习Linq/Lambda表达式,并被卡在某个地方.

I am trying to learn the Linq/Lambda expressions and was stuck at somewhere.

我在做什么

我创建了两个具有属性的类,这些属性具有一些共同的属性.这些类就像(这是测试代码).

I have created two classes with properties which have some common properties in them. The classes are like(It's test code).

class TestA
    {
        public int Id { get; set; }
        public int ProductID { get; set; }
        public string Category { get; set; }

        public TestA(int id, int procid, string category)
        {
            this.Id = id;
            this.ProductID = procid;
            this.Category = category;
        }
    }

    class TestB
    {
        public int ProductID { get; set; }
        public string Category { get; set; }

        public TestB(int procid, string category)
        {
            this.ProductID = procid;
            this.Category = category;
        }
    }

然后我为他们创建了两个列表

Then I created the two list for them as,

        List<TestA> testListA = new List<TestA>();
        List<TestB> testListB = new List<TestB>();
        TestA t1 = new TestA(1, 254, "ProductA");
        TestA t2 = new TestA(1, 236, "ProductA");
        TestA t3 = new TestA(1, 215, "ProductB");
        TestA t4 = new TestA(1, 175, "ProductB");
        TestA t5 = new TestA(1, 175, "ProductC");
        testListA.Add(t1);
        testListA.Add(t2);
        testListA.Add(t3);
        testListA.Add(t4);
        testListA.Add(t5);

        TestB tt1 = new TestB(254, "ProdcutA");
        TestB tt2 = new TestB(215, "ProductB");
        TestB tt3 = new TestB(175, "ProductC");
        testListB.Add(tt3);
        testListB.Add(tt2);
        testListB.Add(tt1);

现在我想要结果t2,因为它是ProductID匹配项,不在testListB中 和t4,因为它在testListB中具有匹配的ProductID,但没有相同的Category.
1)我需要每个记录的List<A>:在testListB中不再保存ProductID

Now for result I wanted t2 as it's ProductID match is not in the testListB And t4 as it has matching ProductID in testListB but don't have the same Category.
1) I need a List<A> of every record which: No longer has a ProductID held in the testListB

我可以得到它,

  testListA.Select(x => x.ProductID).Except(testListB.Select(x => x.ProductID ));

2)不再具有在testListB中具有匹配的ProductIDCategory的记录

2)No longer has a record which has a matching ProductID and Category in testListB

我可以使用的

   testListA.Where(a => testListB.Any(b => a.ProductID == b.ProductID && a.Category != b.Category));

**我的问题**
我可以考虑使用实现IEqualityComparer,但是我不确定如何为两种不同类型的类实现GetHashCode.因此,可以将上述查询合并为单个查询,也可以通过其他任何方式对两种不同类型的类隐含自定义Comparer.还是有其他简单的方法吗?

**My Question **
Is it possible two make single linq expression to get result.I thought of using the implement IEqualityComparer but I am not sure how to implement the GetHashCode it for two different type of classes. So either combining the above query into single query or any other way to impliment custom Comparer for two different Type of classes. Or is there any other simple way?

推荐答案

您已经说过,您只需要testListA中的这些对象:

You have said that you need only these objects from testListA:

  • testListB中没有匹配的ProductID
  • 存在现有的数学ProductID,但具有不同的Category
  • there is not matching ProductID in testListB
  • there is existing mathing ProductID, but with different Category

因此,您的过滤器必须是:

So, your filter must be:

!testListB.Any(b => a.ProductID == b.ProductID && a.Category == b.Category)

因此,将您的代码更改为:

So, change your code as:

testListA.Where(a => !testListB.Any(b => a.ProductID == b.ProductID && a.Category == b.Category));


第二种方法:


Second approach:

或者您可以从第二个列表中创建一个新的List<TestA>:

Or you can create a new List<TestA> from the second list:

 var secondListA = testListB.Select(x=> new TestA(){Category=x.Category, ProductID=x.ProductID}).ToList();

然后创建您的Comparer:

sealed class MyComparer : IEqualityComparer<TestA>
{
    public bool Equals(TestA x, TestA y)
    {
        if (x == null)
            return y == null;
        else if (y == null)
            return false;
        else
            return x.ProductID == y.ProductID && x.Category == y.Category;
    }

    public int GetHashCode(TestA obj)
    {
        return obj.ProductID.GetHashCode();
    }
}

并使用 Except() 重载,通过使用指定的IEqualityComparer<T>比较值来产生两个序列的集合差.:

And use Except() overload which produces the set difference of two sequences by using the specified IEqualityComparer<T> to compare values.:

var result = testListA.Except(secondListA, new MyComparer ()).ToList();

这篇关于如何使用具有不同类的多个属性的linq`Except`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆