对象列表与对象列表的交叉列表

Saa*_*ani 3 c# linq

我有一个交易类别列表:

class Transactions
{
    public Transactions()
    {
        Products = new List<Product>();
    }

    public string Date { get; set; }

    public string TransactionID { get; set; }

    public List<Product> Products { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和产品类别:

class Product
{
    public decimal ProductCode { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我有一个这样的产品列表:

List<Product> unioned = product.Union(secondProduct).ToList();
Run Code Online (Sandbox Code Playgroud)

我想要联合产品和交易产品的交集,此代码不起作用:

var intersection = transactions.Where(q => q.Products.Intersect(unioned).Any());
Run Code Online (Sandbox Code Playgroud)

我认为原因是交易产品长度不同而联合长度是固定的。

我该怎么做?

stu*_*rtd 6

Intersect 使用默认的相等比较器,因此将进行引用检查 - 即比较对象引用是否相同。

您需要使用允许您指定相等比较器的重载

因此:

public class ProductComparer : IEqualityComparer<Product>
{
    public bool Equals(Product x, Product y)
    {
        // TODO - Add null handling.
        return x.ProductCode == y.ProductCode;
    }

    public int GetHashCode(Product obj)
    {
        return obj.ProductCode.GetHashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)

进而:

var intersection = transactions
                  .Where(q => q.Products.Intersect(unioned, new ProductComparer()).Any());
Run Code Online (Sandbox Code Playgroud)

现在该测试将通过:

[TestMethod]
public void T()
{
    Product p = new Product { ProductCode = 10M };
    List<Product> product = new List<Product> { p };
    List<Product> secondProduct = new List<Product> { new Product { ProductCode = 20M } };
    List<Product> unioned = product.Union(secondProduct).ToList();
     var transaction = new Transactions();
     // add a different object reference
     transaction.Products.Add(new Product { ProductCode = 10M }); 

     IList<Transactions>  transactions = new List<Transactions> { transaction };

     var intersection = transactions
                  .Where(q => q.Products.Intersect(unioned, new ProductComparer()).Any());

     Assert.AreEqual(1, intersection.Count());
}
Run Code Online (Sandbox Code Playgroud)