title: Compare two lists of object for new, changed, updated on a specific property
body: <p>I've been trying and failing for a while to find a solution to compare to lists of objects based on a property of the objects. I've read other similar solutions but they were either not suitable (or I didn't understand the answer!).</p>
  
  <p>Code is C#</p>
  
  <p>I have a model that represents an image</p>
  
  <pre><code>public class AccommodationImageModel
  {
      public int Id { get; set; }
      public string Path { get; set; }
      public string Caption { get; set; }
      public string Description { get; set; }
      public bool CoverImage { get; set; }
      public bool Visible { get; set; }     
  }
  </code></pre>
  
  <p>I have two lists of this model. One is the existing list, another is an updated list.  I need to compare the two lists to see which have been removed, updated or are new.</p>
  
  <p>I don't need to compare the whole object, just compare them on their property Id.</p>
  
  <pre><code>List&lt;AccommodationImageModel&gt; masterList;
  List&lt;AccommodationImageModel&gt; compareList;
  </code></pre>
  
  <h3>New</h3>
  
  <p>If compareList contains any AccommodationImageModel with Id=0 then they are new because new entries do not have an Id assigned yet.</p>
  
  <h3>To be deleted</h3>
  
  <p>If masterList contains any AccommodationImageModel with Ids that are Not in compareList then they are to be deleted, because they have been removed from the compareList and should be removed from the masterList. Therefore I need a list of the ones that need to be deleted.</p>
  
  <h3>To be updated</h3>
  
  <p>If newList and masterList have Id's that are the same then they are to be updated. Therefore I need a list of the ones that share the same ID, so I can them update them. I'm not too concerned if these models are identical and don't need updating as there will only be a small number per list so it doesn't matter much if they get updated even if they haven't changed.</p>
  
  <p>Each of the three results needs to be returned as a List of AccommodationImageModel so that I can then carry out the appropriate update, remove, add.</p>
  
  <h2>Edit</h2>
  
  <p>I've added 3 test methods below with my chosen solution from ATM, showing its working implementation.</p>
  
  <h3>Test methods</h3>
  
  <pre><code>[TestMethod]
      public void Test_Deleted_Image()
      {
          // set up the masterList
          List&lt;AccommodationImageModel&gt; masterList = new List&lt;AccommodationImageModel&gt;();
          masterList.Add(new AccommodationImageModel { Id = 1 });
          masterList.Add(new AccommodationImageModel { Id = 2 });
  
          // set up the compare list
          List&lt;AccommodationImageModel&gt; compareList = new List&lt;AccommodationImageModel&gt;();
          compareList.Add(new AccommodationImageModel { Id = 1 });
          compareList.Add(new AccommodationImageModel { Id = 3 });
          compareList.Add(new AccommodationImageModel { Id = 0 });
  
          // get the deleted models
          List&lt;AccommodationImageModel&gt; result = masterList.Where(c =&gt; !compareList.Any(d =&gt; d.Id == c.Id)).ToList();
  
          // result should hold first model with id 2
          Assert.AreEqual(2, result.FirstOrDefault().Id);
      }
  
      [TestMethod]
      public void Test_Added_Image()
      {
          // set up the masterList
          List&lt;AccommodationImageModel&gt; masterList = new List&lt;AccommodationImageModel&gt;();
          masterList.Add(new AccommodationImageModel { Id = 1 });
          masterList.Add(new AccommodationImageModel { Id = 2 });
  
          // set up the compare list
          List&lt;AccommodationImageModel&gt; compareList = new List&lt;AccommodationImageModel&gt;();
          compareList.Add(new AccommodationImageModel { Id = 1 });
          compareList.Add(new AccommodationImageModel { Id = 3 });
          compareList.Add(new AccommodationImageModel { Id = 0 });
  
          // get the added models
          List&lt;AccommodationImageModel&gt; result = compareList.Where(c =&gt; c.Id == 0).ToList();
  
          // result should hold first model with id 0
          Assert.AreEqual(0, result.FirstOrDefault().Id);
      }
  
      [TestMethod]
      public void Test_Updated_Image()
      {
          // set up the masterList
          List&lt;AccommodationImageModel&gt; masterList = new List&lt;AccommodationImageModel&gt;();
          masterList.Add(new AccommodationImageModel { Id = 1 });
          masterList.Add(new AccommodationImageModel { Id = 2 });
  
          // set up the compare list
          List&lt;AccommodationImageModel&gt; compareList = new List&lt;AccommodationImageModel&gt;();
          compareList.Add(new AccommodationImageModel { Id = 1 });
          compareList.Add(new AccommodationImageModel { Id = 3 });
          compareList.Add(new AccommodationImageModel { Id = 0 });
  
          // get the updated models
          List&lt;AccommodationImageModel&gt; result = masterList.Where(c =&gt; compareList.Any(d =&gt; c.Id == d.Id)).ToList();
  
          // result should hold first model with id 1
          Assert.AreEqual(1, result.FirstOrDefault().Id);
      }
  </code></pre>