I am getting a "Primary key violation" error when EF Core is attempting to update a M-to-M relationship.
Here is the code:
// Find the Contact
Contact? Contact = await repository.GetEntityAsync(ContactDto?.Id ?? -1, cancellationToken);
// Check for null
if (Contact == null)
{
return new OperationResultDto()
{
Success = false,
Error = "Contact not found"
};
}
mapper.Map(ContactDto, Contact);
Contact resultingContact = await repository.UpdateEntityAsync(Contact, cancellationToken); // << ERROR HERE
Here are the model classes:
public class ContactDto
{
public int Id { get; set; }
public IEnumerable<Role>? Roles { get; set; }
}
public class Contact
{
public int Id { get; set; }
public virtual ICollection<Role>? Roles { get; set; }
}
public class Role
{
public Role() => Contacts = new HashSet<Contact>();
public ContactType Type { get; set; }
public virtual ICollection<Contact> Contacts { get; set; }
}
Fluent API:
/* Role Table */
modelBuilder.Entity<Role>(entity =>
{
entity.HasKey(e => e.Type);
entity.HasMany(e => e.Contacts)
.WithMany(e => e.Roles);
});
/* Contact table */
modelBuilder.Entity<Contact>(entity =>
{
entity.Property(e => e.TradingName).HasMaxLength(100);
entity.Property(e => e.ParentId);
entity.HasMany(e => e.Roles)
.WithMany(e => e.Contacts);
});
When I look at the SQL in the debug it is this:
UPDATE [Contacts]
SET [BreedEnumValue] = @p14, [CategoryEnumValue] = @p15,
[Destination] = @p16, [ERPStatus] = @p17, [EuComply] = @p18,
[Freight] = @p19, [Halal] = @p20, [MSA] = @p21,
[NonHGP] = @p22, [ParentId] = @p23, [QualityCode] = @p24,
[SaudiComply] = @p25, [Specie] = @p26, [TradingName] = @p27,
[TransportBy] = @p28, [TransportMode] = @p29
WHERE [Id] = @p30;
SELECT @@ROWCOUNT;
INSERT INTO [Role] ([Type])
VALUES (@p31), (@p32);
It is trying to update the Roles table, but the roles table is already populated. Why is this happening? Should it not find the TYPE ID?