title: DDD: Aggregate design - Referencing between aggregates
body: <p>I have an issue with how to design aggregates.</p>
  
  <p>I have <code>Company</code>, <code>City</code>, <code>Province</code> and <code>Country</code> entities.  Each of these needs to be an aggregate root of its own aggregate.  The <code>City</code>, <code>Province</code> and <code>Country</code> entities are used throughout the system and are referenced by many other entities, so they are not value objects and also need to be accessed in many different scenarios.  So they should have repositories.  A <code>CityRepository</code> would have methods such as <code>FindById(int)</code>, <code>GetAll()</code>, <code>GetByProvince(Province)</code>, <code>GetByCountry(Country)</code>, <code>GetByName(string)</code>.</p>
  
  <p>Take the following example.  A <code>Company</code> entity is associated with a <code>City</code>, which belong to a <code>Province</code> which belongs to a <code>Country</code>:</p>
  
  <p><img src="https://i.stack.imgur.com/5vLwE.png" alt="Aggregate Roots"></p>
  
  <p>Now let's say we have a company listing page which lists some companies with their city, province and country.</p>
  
  <h2>Reference by ID</h2>
  
  <p>If an entity needs to reference a <code>City</code>, <code>Province</code> or <code>Country</code>, they would do so by ID (as suggested by Vaughn Vernon).  </p>
  
  <p>In order to get this data from the repositories, we need to call 4 different repositories and then match up the data in order to populate the view.</p>
  
  <pre><code>var companies = CompanyRepository.GetBySomeCriteria();
  var cities = CityRepository.GetByIds(companies.Select(x =&gt; x.CityId);
  var provinces = ProvinceRepository.GetByIds(cities.Select(x =&gt; x.ProvinceId);
  var countries = CountryRepository.GetByIds(province.Select(x =&gt; x.CountryId);
  
  foreach(var company in companies)
  {
      var city = cities.Single(x =&gt; x.CityId == company.CityId);
      var province = provinces.Single(x =&gt; x.ProvinceId == city.ProvinceId);
      var country = countries.Single(x =&gt; x.CountryId == province.CountryId);
  
      someViewModel = new CompanyLineViewModel(company.Name, city.Name, province.Name, country.Name);
  }
  </code></pre>
  
  <p>This is a very bulky and inefficient, but apparently the 'correct' way?</p>
  
  <h2>Reference by Reference</h2>
  
  <p>If the entites were referenced by reference, the same query would look like this:</p>
  
  <pre><code>var companies = CompanyRepository.GetBySomeCriteria();
  someViewModel = new CompanyLineViewModel(company.Name, company.City.Name, company.Province.Name, company.Country.Name);
  </code></pre>
  
  <p>But as far as I understand, these entities cannot be referenced by reference as they exist in different aggregates.</p>
  
  <h2>Question</h2>
  
  <p><strong>How else could I better design these aggregates?</strong></p>
  
  <p>Could I load company entities with the city model even when they exist in different aggregates?  I imagine this would soon break the boundaries between aggregates.  It would also create confusion when dealing with transactional consistency when updating aggregates.</p>