Linq:找到具有共同属性但不同类型的元素

时间:2016-11-10 12:05:17

标签: c# linq

我有两个包含对象的列表:

class Class1
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Guid UniqueIdentifier { get; set; }
    public bool IsValid { get; set; }
}

class Class2
{
    public int Identifier { get; set; }
    public string Producer{ get; set; }
    public Guid Guid { get; set; }
    public int SupplierId { get; set; }
}

有没有办法使用linq从列表中获取类型Class1的元素,这些元素具有相同的Id(标识符)和Guid元素从第二个列表中输入Class2

4 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

var result = from item1 in list1
             join item2 in list2 on 
                    new { G = item1.UniqueIdentifier, Id = item1.Id }  
             equals new { G = item2.Guid, Id = item2.Identifier }
             select new { item1, item2 };

foreach(var item in result)
{
    Console.WriteLine($"Producer: {item.item2.Producer} with product: {item.item1.Name}");
}

答案 1 :(得分:1)

这是一种方法:

var result = list1
    .Where(x => list2.Any(y => x.Id == y.Identifier && x.UniqueIdentifier == y.Guid))
    .ToList();

请注意,此版本未针对大型列表进行优化。如果你的名单很小,这很好。如果您有大型列表,则需要一个涉及HashSet s之类的解决方案。这是一个例子:

var list2HashSet = CreateHashset(list2.Select(x => new {x.Identifier, x.Guid}));

var result = list1
    .Where(x => list2HashSet.Contains(new {Identifier = x.Id, Guid = x.UniqueIdentifier}))
    .ToList();

CreateHashset的定义如下:

public static HashSet<T> CreateHashset<T>(IEnumerable<T> collection)
{
    return new HashSet<T>(collection);
}

我必须创建这个简单的方法,因为编译器抱怨它无法解析正确的构造函数重载。我不确定为什么。

答案 2 :(得分:0)

我们假设您有两个列表

List<Class1> List1;
List<Class2> List2;

您可以使用

选择包含第二个列表的Id和Guid的List1的所有项目
List1.Where(C1 => List2.Any(C2 => C1.Id == C2.Identifier && C1.UniqueIdentifier == C2.Guid));

请注意,Guid是一个类。如果您不想检查C1.UniqueIdentifierC2.Guid是否完全相同,则应implement IsEqual并使用它

List1.Where(C1 => List2.Any(C2 => C1.Id == C2.Identifier && C1.UniqueIdentifier.Equals(C2.Guid)));

答案 3 :(得分:0)

如果ids或guids匹配就足够了,请参阅Jeroen van Langen的答案。否则,我看到两个选项:

  1. 之后添加where子句,即

    var result =来自list1中的item1              item1.Id等于item2.Identifier,在list2中加入item2              其中item1.UniqueIdentifier = item2.Guid              选择新的{item1,item2};

  2. 创建一个元组类并加入Guid和Id的元组。您不能重用.NET 4元组类型(Tuple<,>),但您可以重用C#7元组类型,因为它们正确地实现了相等。

  3. 对于大型列表,两个版本也应该没问题。基本上,只要你使用join,整个事情就应该扩展。