2016-09-20 111 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; 
}