-1

我有两个 List 实例,即 OldCustomers、NewCustomers。

List<Customer> OldCustomers;

List<Customer> NewCustomers;

我只想要老客户和新客户的联合。也就是说,如果 CustomerID 100 存在于 OldCustomerList 和 NewCustomer 列表中,则必须删除 OldCustomer 列表中的客户详细信息,并且必须将 NewCustomer 列表放置在结果列表中,如下所示。

List<Customer> NewCustomers;
    Union
List<Customer> OldCustomers;

我如何在 LINQ 中做到这一点?

提前致谢,

4

6 回答 6

1

为了使用Union,您必须自定义EqualityComparer

public class CusComparer : EqualityComparer<Customer>
{
    public override bool Equals(Customer x, Customer y)
    {
        return x.CustomerID == y.CustomerID;
    }

    public override int GetHashCode(Customer obj)
    {
        return obj.CustomerId.GetHashCode();
    }
}

然后:

var unionCustomers = NewCustomers.Union(OldCustomers, new CusComparer());
于 2012-10-10T06:47:14.177 回答
0

因此,您要获取所有新客户和所有不在新列表中的旧客户:

List<Customer> customers = NewCustomers.Concat(OldCustomers.Except(NewCustomers)).ToList();

请记住实现IEqualityComparer<T>通用接口来比较您的客户(可能通过CustomerID)。GetHashCode因此,您需要EqualsCustomer.

这是一个可能的实现:

public class Customer 
{
    public int CustomerID { get; set; }
    public string CustomerName { get; set; }

    public override bool Equals(Object obj)
    {
        Customer cust = obj as Customer;
        if (cust == null) return false;
        return cust.CustomerID == CustomerID;
    }

    public override int GetHashCode()
    {
        return CustomerID.GetHashCode();
    }

    public class Comparer : IEqualityComparer<Customer>
    {
        public bool Equals(Customer x, Customer y)
        {
            if (x == null && y == null) return true;
            if (x == null || y == null) return false;
            return x.Equals(y);
        }

        public int GetHashCode(Customer obj)
        {
            if (obj == null) return -1;
            return obj.GetHashCode();
        }
    }
}

请注意,我覆盖EqualsGetHashCodeCustomer. 通过这种方式,您甚至不需要传递 to 的实例IEqualityComparer<Customer>Except或任何其他允许传递比较器的方法)。

但为了完整起见,我还添加了Comparer实现接口的类,因此您也可以将其传递给 except:

NewCustomers.Concat(OldCustomers.Except(NewCustomers, new Customer.Comparer()));
于 2012-10-10T06:58:24.153 回答
0

你可以像这样使用联合函数

sequence1.Union(sequence2)

IE

var custlist =  NewCustomers.Union(OldCustomers).ToList(); 

阅读:Enumerable.Union 方法(IEnumerable、IEnumerable)

例子 :

            int[] ints1 = { 5, 3, 9, 7, 5, 9, 3, 7 };
            int[] ints2 = { 8, 3, 6, 4, 4, 9, 1, 0 };

            IEnumerable<int> union = ints1.Union(ints2);

            foreach (int num in union)
            {
                Console.Write("{0} ", num);
            }

            /*
             This code produces the following output:

             5 3 9 7 8 6 4 1 0
            */
于 2012-10-10T06:36:40.003 回答
0

你可以使用Union喜欢

var union = NewCustomers.Union(OldCustomers);

并且可能您将不得不为您的班级实现自己的比较器Customer

于 2012-10-10T06:37:57.293 回答
0

Union将比较客户对象的实例(如果IEqualityComparer未使用)。我想你正在寻找类似的东西UnionBy

var finalList = NewCustomers.Concat(OldCustomers)
                    .GroupBy(x => x.CustomerID)
                    .Select(x => x.First())
                    .ToList();

- 编辑 -

一个可能的UnionBy实现:

var finalList = NewCustomers.UnionBy(OldCustomers, c => c.CustomerID).ToList();

-

public static class SOExtension
{

    public static IEnumerable<T> UnionBy<T,V>(this IEnumerable<T> list, IEnumerable<T> otherList,Func<T,V> selector)
    {
        HashSet<V> set = new HashSet<V>();

        foreach (T t in list)
        {
            set.Add(selector(t));
            yield return t;
        }
        foreach(T t in otherList)
        {
            if(!set.Contains(selector(t)))
                yield return t;
        }
    }
}
于 2012-10-10T06:46:06.270 回答
0
HashSet<Customer> set = new HashSet<Customer>(list1);
set.SymmectricExceptWith(list2); // Or other userful methods.
于 2012-10-10T07:16:49.940 回答