2016-11-17 91 views
1

我试图使用LINQ-如何合并两个列表和合并它在C#中没有重复内列出

List<LinkedTable> FirstLink 
List<LinkedTable> SecondLink 

合并两个泛型列表如下面的类所示,我的泛型列表本身有一个通用的列表中。

public class LinkedTable 
{ 
    public string TableId { get; set; } 
    public string TableName { get; set; } 
    public List<Link> innerLinks { get; set; } 
} 

public class Link 
{ 
    public Boolean linkFlag; 
    public string Descriptor { get; set; } 
    public string RecordId { get; set; } 
} 

当我合并这两个列表时,新列表不包含FirstLink和SecondLink的“innerLinks”记录。 我曾尝试下面的代码:

FirstLink = FirstLink.Concat(SecondLink) 
        .GroupBy(e1 => e1.TableId) 
        .Select(e2 => e2.FirstOrDefault()) 
        .ToList(); 

现在首联将获得由“TABLEID”分组的所有表,但也有少数“innerLinks”从是secondlink丢失。

我需要FirstLink和SecondLink在新合并列表中的“innerLinks”列表而不重复。

例子:

FirstLink[0].innerLinks[0] 
      .innerLinks[1] 
      .innerLinks[2] 

SecondLink[0].innerLinks[1] 
      .innerLinks[2] 
      .innerLinks[3] 

合并链接应该是:

FirstLink[0].innerLinks[0] 
      .innerLinks[1] 
      .innerLinks[2]    
      .innerLinks[3] 
+1

你试过像'的foreach(在VAR是secondlink项目){FirstLink.Add(项目);}' – Sam07

+0

的可能的复制[如何使用LINQ合并两个列表?(http://stackoverflow.com/questions/4872943/how-to-merge-two-lists-using-linq) –

回答

1

这里有一个选项:

首先,你必须提供一种方式来告诉的LINQ是什么让一个链接等于另一个。您可以通过任何的这个方法做到这一点:

  • 创建类的工具IEqualityComparer<Link>,并通过它的一个实例作为参数传递给Distinct;
  • 链接类
  • 链接类中重写EqualsGetHashCode实施IEquatable<Link>和压倒一切的GetHashCode

假设的recordId是一个链接对象的唯一标识,这是你如何通过实现IEquatable<Link>做到这一点:

public class Link : IEquatable<Link> 
{ 
    public Boolean linkFlag; 
    public string Descriptor { get; set; } 
    public string RecordId { get; set; } 

    public bool Equals(Link other) 
    { 
     //Adjust for a suiting identifier and do all the sanity checks, if needed. 
     return this.RecordId == other.RecordId; 
    } 

    public override int GetHashCode() 
    { 
     //You can also use another GetHash approach that suits you better. 
     return this.RecordId.GetHashCode(); 
    } 
} 

然后,您可以Concat两份名单,然后由tableId和表名组。最后,在组合的LinkedTable的innerLinks上使用SelectMany来选择该组中包含的所有链接。如果您选择这种方式,Distinct将不得不采取IEqualityComparer的实例。

var merged = 
    from item in FirstLink.Concat(SecondLink) 
    group item by new { Id = item.TableId, Name = item.TableName } into tbGp 
    select new LinkedTable 
    { 
     TableId = tbGp.Key.Id, 
     TableName = tbGp.Key.Name, 
     innerLinks = tbGp.SelectMany(p => p.innerLinks).Distinct().ToList() 
    }; 

DistinctIEquatable<T>解释on MSDN
重写EqualsGetHashCodeon MSDN

1

因为当你分组你正在服用的集团和Link对象列表的第一个元素您的查询不工作

要实现你的结果,你应该尝试下面的代码:

var FirstLink = FirstLink 
    .Concat(SecondLink) 
    .GroupBy(e1 => e1.TableId) 
    // Don't take the first item, but create a new one with the items you need 
    .Select(e2 => new LinkedTable 
     { 
      TableId = e2.Key, 
      TableName = e2.First().TableName, 
      innerLinks = e2.SelectMany(x => x.innerLinks).ToList() 
     }) 
    .ToList();