【问题标题】:Is there a way in C# to use EXCEPT to compare 2 lists when one doesn't have Id yet?C# 中有没有办法在一个还没有 Id 的情况下使用 EXCEPT 来比较 2 个列表?
【发布时间】:2021-08-02 18:44:00
【问题描述】:

我从数据库中得到 listA。我从最终用户上传的文件中获取 listB,然后将其转换为列表中的正确类。对于这个例子,我给你一个来自数据库的列表和一个用户上传的列表。您可以在下面找到这些示例。

我需要检查 listB 是否在 listA 中,但是当我使用 Except 时,我会得到整个列表,因为 Id 不在 listB 中(数据库中的自动编号)。我现在有一个解决方案,但有更好的方法吗?

到目前为止我所做的尝试:

List<CustomerGroup> listC = listA.Except(listB).ToList(); 
    //Returns listA in listC because Id isn't the same

这是我现在正在使用的,但它似乎很多余。

foreach (CustomerGroup itemToCheck in listB)
{
    var foundItem = listA.Find(dbItem => dbItem.FirstName== itemToCheck.FirstName &&
                                            dbItem.FamilyName== itemToCheck.FamilyName &&
                                            dbItem.Quantity == itemToCheck.Quantity &&
                                            dbItem.Discount == itemToCheck.Discount);
    if(foundItem != null)
    {
        listA.Remove(foundItem);
        listB.Remove(itemToCheck);
    }
}

foreach (CustomerGroup itemToCheck in listB)
{
    // other code to check here
}
List<CustomerGroup> listA = new List<CustomerGroup>(){
   new CustomerGroup {Id = 1, FirstName = "Anna", FamilyName = "Shrek", Quantity = 5, Discount = 10},
   new CustomerGroup {Id = 2, FirstName = "Elsa", FamilyName = "Fiona", Quantity = 5, Discount = 10},
   new CustomerGroup {Id = 3, FirstName = "Olaf", FamilyName = "Donkey", Quantity = 5, Discount = 10},
   new CustomerGroup {Id = 4, FirstName = "Sven", FamilyName = "Dragon", Quantity = 5, Discount = 5},
   new CustomerGroup {Id = 5, FirstName = "Kristoff", FamilyName = "Puss", Quantity = 5, Discount = 10},
   new CustomerGroup {Id = 6, FirstName = "Sven", FamilyName = "Dragon", Quantity = 10, Discount = 15},
   new CustomerGroup {Id = 7, FirstName = "Kristoff", FamilyName = "Puss", Quantity = 10, Discount = 30}
};
List<CustomerGroup> listB = new List<CustomerGroup>(){
   new CustomerGroup { FirstName = "Anna", FamilyName = "Shrek", Quantity = 5, Discount = 10},
   new CustomerGroup { FirstName = "Elsa", FamilyName = "Fiona", Quantity = 5, Discount = 8},
   new CustomerGroup { FirstName = "Sven", FamilyName = "Dragon", Quantity = 5, Discount = 5},
   new CustomerGroup { FirstName = "Kristoff", FamilyName = "Puss", Quantity = 5, Discount = 10},
   new CustomerGroup { FirstName = "Sven", FamilyName = "Dragon", Quantity = 10, Discount = 15},
   new CustomerGroup { FirstName = "Kristoff", FamilyName = "Puss", Quantity = 10, Discount = 30},
   new CustomerGroup { FirstName = "Hans", FamilyName = "Farquaad", Quantity = 20, Discount = 40}
};
public class CustomerGroup{
    public int Id {get; set;}
    public string FirstName {get; set;}
    public string FamilyName {get; set;}
    public int Quantity{get; set;}
    public int Discount {get; set;}
}

【问题讨论】:

标签: c# list linq except


【解决方案1】:

您可以使用自己的IEqualityComparer,忽略ID 属性:

class MyEqualityComparer : IEqualityComparer<CustomerGroup>
{
    public bool Equals(CustomerGroup x, CustomerGroup y)
    {
        if(x is null) return y is null;
        if(y is null) return false;
        return x.FirstName == y.FirstName && x.FamilyName == y.FamilyName && x.Quantity == y.Quantity && x.Discount == y.Discount;
    }
    
    public int GetHashCode(CustomerGroup codeh)
    {
        return 0;
    }
}

将此传递给Except

List<CustomerGroup> listC = listA.Except(listB, new MyEqualityComparer()).ToList();

在线演示:https://dotnetfiddle.net/gogy9g

【讨论】:

  • 这是一个很好的答案!为什么返回 'y is null' 而不是 'false'?
  • 当 x 为空时,代码检查 y 是否也为空。如果是这样,那么两者都是空的,因此相等。但是当再次阅读它时,我才意识到如果只有 y 为空,这将失败(稍后将抛出 NullReferenceException 一行)。我会更新我的答案。
  • 还请注意,这可能会很慢,因为所有实例都将具有相同的哈希码。如果您的列表非常庞大,Prasad Telkikar 的解决方案可能会更好。
【解决方案2】:

为类CustomerGroup实现IEqualityComparer&lt;&gt;,然后使用Except()

喜欢,

public class CompareCustomerGroup : IEqualityComparer<CustomerGroup>
{
    public bool Equals(CustomerGroup dbCustomer, CustomerGroup uploadedCustomer)
    {
        if(dbCustomer == null || uploadedCustomer == null)
            return false;
        else 
             return dbCustomer.FirstName == uploadCustomer.FirstName &&
             dbCustomer.FamilyName == uploadCustomer.FamilyName &&
             dbCustomer.Quantity == uploadCustomer.Quantity &&
             dbCustomer.Discount == uploadCustomer.Discount;
             
    }

    public int GetHashCode(CustomerGroup customGroup)
    {
        return HashCode.Combine(customGroup.FirstName, customGroup.FamilyName , customGroup.Quantity, customGroup.Discount);
    }
} 

现在试试Except()

List<CustomerGroup> listC = listA.Except(listB, new CompareCustomerGroup()).ToList(); 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-19
    • 2013-07-09
    • 2019-07-07
    • 2016-01-10
    • 2016-01-19
    相关资源
    最近更新 更多