2016-09-20 43 views
1

假设我有一个Person类,如下所示,其中有两个Person集合实例,第一个实例是包含所有记录的主集合,而第二个实例实例是主集合的一个子集。C#Linq - 匹配两组数据并更新匹配的第一组

我需要做的是更新主集的IsMatched属性,其中实例也存在于子集中。

public class Person 
{ 
    public int Id { get; set; } 

    public string Title { get; set; } 

    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public bool IsMatched { get; set; } 
} 

可枚举IntersectAny是使用匹配和更新主数据集?

基于Tim的建议我创建一个单元测试来测试解决方案

[TestFixture()] 
    public class Test 
    { 
     [TestFixture] 
     public class MatchedSetTest 
     { 
      private class Person 
      { 
       public int Id { get; set; } 

       public string Title { get; set; } 

       public string FirstName { get; set; } 

       public string LastName { get; set; } 

       public bool IsMatched { get; set; } 
      } 

      [Test] 
      public void TestMatchingSets() 
      { 
       var members = new List<Person>() 
       { 
        new Person() { FirstName = "Tom", LastName = "Smith", Id = 1, Title = "Mr", IsMatched = false} , 
        new Person() { FirstName = "Paul", LastName = "Jones", Id = 2, Title = "Mr", IsMatched = false} , 
        new Person() { FirstName = "Gary", LastName = "Thompson", Id = 3, Title = "Mr", IsMatched = false} , 
        new Person() { FirstName = "Simon", LastName = "Green", Id = 4, Title = "Mr", IsMatched = false} , 
        new Person() { FirstName = "Phil", LastName = "Stuart", Id = 5, Title = "Mr", IsMatched = false} , 
        new Person() { FirstName = "Sean", LastName = "Appleton", Id = 6, Title = "Mr", IsMatched = false} 
       }; 

       var buddy = new List<Person>() 
       { 
        new Person() { FirstName = "Tom", LastName = "Smith", Id = 1, Title = "Mr", IsMatched = false} , 
        new Person() { FirstName = "Gary", LastName = "Thompson", Id = 3, Title = "Mr", IsMatched = false} , 
        new Person() { FirstName = "Simon", LastName = "Green", Id = 4, Title = "Mr", IsMatched = false} 
       }; 

       var existing = from m in members 
           join s in buddy on m.Id equals s.Id 
           select new { Master = m, Subset = s }; 

       foreach (var both in existing) 
       { 
        both.Master.IsMatched = both.Subset.IsMatched; 
       } 

      var p = existing.Where(w => w.Master.Id == 1).FirstOrDefault().Master; 
      Assert.IsTrue(p.IsMatched); 

      } 

     } 

    } 

现有的对象包含与内的主机和子集实例和所有实例IsMatched性能从子集的三个项目仍然假。

我需要的是整个主集合返回时,匹配的主集合实例上的子集中的匹配项将IsMatched属性标记为true。

另一个选项

这会是一个合适的解决方案?

buddy.ForEach(b => 
{ 
    var member = members.FirstOrDefault(w => w.Id == b.Id); 

    if (member != null) 
     member.IsMatched = true; 
}); 
+0

多少项做这些集合包含哪些内容? – Fabjan

+0

主集包含大约9000行,而子集可能包含50-100 –

回答

1

您可以加入他们的行列,无论是存储在一个匿名的类型,然后使用foreach:

var existing = from m in master join s in subset on m.Id equals s.Id 
       select new { Master = m, Subset = s }; 
foreach (var both in existing) 
{ 
    both.Master.IsMatched = both.Subset.IsMatched; 
} 

注意,这个假设有每个主只有一个子集。如果你有重复的结果可能是任意的,因为最后一个子集人获胜。

+0

感谢Tim,但IsMatched属性对于ForEach之前和之后的现有匿名类型中的所有实体似乎都是false。如何从IsMatched设置为true的匿名类型获取主集合? –

+0

它似乎也只是从子集集合中返回匹配的Person实例 –

+0

我认为在foreach循环中,您需要使用以下代码both.Master.IsMatched = true –

-1

下面的片段将在personListB存在,并在那里与personListB匹配记录有IsMatched设置为True(匹配的记录是基于Id属性)只返回personListA记录。

personListA.Where(pla => personListB.Any(plb => plb.Id == pla.Id && plb.IsMatched)); 

Working Demo in .NET Fiddle

+0

返回无匹配。 –

+0

添加了工作演示的链接。如果两个列表都有一个具有相同Id的人员并且personListB中的实例将IsMatched设置为true,它将仅返回匹配项。 –

0

使用在你的单元测试

var existing = from m in members 
       join s in buddy on m.Id equals s.Id 
       select new { Master = m, Subset = s }; 

foreach (var both in existing) 
{ 
    both.Master.IsMatched = true; 
}