title: Violation of PRIMARY KEY constraint 'PK_XY'. Cannot insert duplicate key in object 'dbo.XY'
body: <p>Using EF Core, I have a <code>Zone</code> that can have multiple <code>Sol</code> (soils), same <code>Sol</code> can be attached to multiple <code>Zone</code>:</p>
  <pre><code>public class Sol
  {
      // ...  
      public ICollection&lt;Zone&gt; Zones { get; set; } = new List&lt;Zone&gt;();
  }
  
  public class Zone
  {
      // ...
      public ICollection&lt;Sol&gt; Sols { get; set; } = new List&lt;Sol&gt;();        
  }
  
  public override void Configure(EntityTypeBuilder&lt;Zone&gt; builder)
  {
      // ...
      builder
          .HasMany(p =&gt; p.Sols)
          .WithMany(p =&gt; p.Zones);                
  }
  </code></pre>
  <p>When adding my Sols to a Zone however I get the following exception:</p>
  <blockquote>
  <p>Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.</p>
  <p>Microsoft.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK_SolZone'. Cannot insert duplicate key in object 'dbo.SolZone'. The duplicate key value is (1, 2).</p>
  </blockquote>
  <p>Some details of implementation:</p>
  <p>In my controller, when retrieving the object I do</p>
  <pre><code>public override async Task&lt;IActionResult&gt; Edit(int id, [FromQuery] bool fullView)
  {
      var currentZone = _repository.SingleOrDefault(new GetZoneWithPaysAndSolsSpecification(id));
  </code></pre>
  <p>where</p>
  <pre><code>public class GetZoneWithPaysAndSolsSpecification : Specification&lt;Zone&gt;
  {
      public GetZoneWithPaysAndSolsSpecification(int zoneId)
      {
          Query.Where(p =&gt; p.Id == zoneId);
          Query.Include(p =&gt; p.Pays);
          Query.Include(p =&gt; p.Sols);
      }
  }
  </code></pre>
  <p>before updating the object, I convert my ZoneDTO to Zone and then add it to the database:</p>
  <pre><code>protected override void BeforeUpdate(Zone zone, ZoneDTO sourceDto)
  {
      zone.Sols.Clear();
  
      foreach (var solId in sourceDto.SolIds)
      {
          var sol = _repository.GetById&lt;Sol&gt;(solId);
          zone.Sols.Add(sol);
      }
  
      base.BeforeUpdate(zone, sourceDto);
  }
  </code></pre>
  <p>I use the base controller, that uses the <code>BeforeUpdate</code>, like this</p>
  <pre><code>[HttpPost]
  [ValidateAntiForgeryToken]
  public virtual async Task&lt;IActionResult&gt; Edit(TDto dto)
  {
      try
      {
          var entity = FromDto(dto);
          BeforeUpdate(entity, dto);
          await _repository.UpdateAsync(entity);
          return RedirectToAction(nameof(Index));
      }
      catch (Exception ex)
      {
          _logger.LogError(ex, &quot;when editing an object after submit&quot;);
          return PartialView();
      }
  }
  </code></pre>
  <p>The repository code</p>
  <pre><code>public Task UpdateAsync&lt;T&gt;(T entity) where T : BaseEntity
  {
      _dbContext.Entry(entity).State = EntityState.Modified;
      return _dbContext.SaveChangesAsync();
  }
  </code></pre>
  <p>I use AutoMapper</p>
  <pre><code>protected TBussinesModel FromDto(TDto dto)
  {
      return _mapper.Map&lt;TBussinesModel&gt;(dto);
  }
  </code></pre>
  <p>And the mapping is like this</p>
  <pre><code>CreateMap&lt;Zone, ZoneDTO&gt;()
      .ForMember(p =&gt; p.SolIds, o =&gt; o.MapFrom(p =&gt; p.Sols.Select(s =&gt; s.Id).ToArray()))
      .ForMember(p =&gt; p.SolNoms, o =&gt; o.MapFrom(p =&gt; p.Sols.Select(s =&gt; s.Nom).ToArray()))
      .ReverseMap();
  </code></pre>