title: Join and group 2 lists with common key
body: <p>I have two Lists of different classes where State (in Pet) and Region (in Person) can contain same string values. I'm trying to get the output like this:</p>
  
  <p>State/Region1:    </p>
  
  <ul>
  <li><p>pets in State1;</p></li>
  <li><p>people in Region1.</p></li>
  </ul>
  
  <p>Result should be shown for each key value even if one of lists doesn't have it. The code I've made works, but it looks clunky. I wonder if there is other way to perfom it.</p>
  
  <pre><code>        Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund", Region="Texas" };
          Person terry = new Person { FirstName = "Terry", LastName = "Adams", Region="NY" };
          Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss", Region="Texas" };
          Person arlene = new Person { FirstName = "Arlene", LastName = "Huff",Region="Corolado" };
          Person rui = new Person { FirstName = "Rui", LastName = "Raposo",Region="Texas" };
          Person phyllis = new Person { FirstName = "Phyllis", LastName = "Harris", Region="California" };
  
          Pet barley = new Pet { Name = "Barley", Owner = terry, State="NY" };
          Pet boots = new Pet { Name = "Boots", Owner = terry, State="New Jersey" };
          Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte, State="Texas" };
          Pet daisy = new Pet { Name = "Daisy", Owner = magnus, State="NY" };
  
          List&lt;Person&gt; people = new List&lt;Person&gt; { magnus, terry, charlotte,arlene, rui,phyllis };
          List&lt;Pet&gt; pets = new List&lt;Pet&gt; { barley, boots, whiskers, daisy };
  
          //join pets with associated people on Region\State
          var resultQuery =( from pet in pets
                         group pet by pet.State into petGroup
                         join person in people on petGroup.Key equals person.Region into persGroup
                             select new Container { Key = petGroup.Key, Pets = petGroup, People = persGroup }
                         ).ToList();
  
          var persQuery = from person in people
                          group person by person.Region;
          //add people groups that have no equivalent in pet groups to the result
          foreach (IGrouping&lt;string, Person&gt; gr in persQuery)
          {
              if (resultQuery.All(_container =&gt; !_container.Key.Contains(gr.Key)))
                  resultQuery.Add(new Container { Key = gr.Key, Pets = new List&lt;Pet&gt;(), People = gr });//have to use Container here
          }
  
          //show results
          foreach (var _container in resultQuery)
          {
              Console.WriteLine("Key(Region): {0}", _container.Key);
              foreach (Pet pet in _container.Pets) Console.WriteLine(pet.Name);
              foreach (Person per in _container.People)
                  Console.WriteLine(per.FirstName);
          }
  </code></pre>
  
  <hr>
  
  <p>also I had to add class Container instead of using anonymous type to perfrom .Add method</p>