Here are the relevant classes and their configuration:
public class Product
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long ProductId { get; set; }
[Required]
public string ProductName { get; set; }
public ICollection<ProductSpecification> ProductSpecifications { get; set; }
}
public class ProductAttributeValue
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long ProductAttributeValueId { get; set; }
[Required]
public string ProductAttributeValueName { get; set; }
public ICollection<ProductSpecification> ProductSpecifications { get; set; }
}
public class ProductSpecification
{
public long ProductId { get; set; }
public long ProductAttributeValueId { get; set; }
public string Note { get; set; }
public Product Product { get; set; }
public ProductAttributeValue ProductAttributeValue { get; set; }
}
// Configuration in the dbConext
modelBuilder.Entity<ProductSpecification>().HasKey(ps => new { ps.ProductId, ps.ProductAttributeValueId });
modelBuilder.Entity<ProductSpecification>().HasOne(p => p.Product).WithMany(ps => ps.ProductSpecifications).HasForeignKey(ps => ps.ProductId);
modelBuilder.Entity<ProductSpecification>().HasOne(pav => pav.ProductAttributeValue).WithMany(ps => ps.ProductSpecifications).HasForeignKey(ps => ps.ProductAttributeValueId);
In the controller :
public async Task<IActionResult> UpdateProduct([FromRoute] long id, [FromBody] Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != product.ProductId)
{
return BadRequest();
}
Product productToBeUpdated = await _unitOfWork.Repository<Product>().GetEntityList(p => p.ProductId == id).Include(p => p.ProductSpecifications).SingleOrDefaultAsync();
if (productToBeUpdated == null)
{
return NotFound();
}
foreach (ProductSpecification productSpecification in productToBeUpdated.ProductSpecifications.ToList())
{
productToBeUpdated.ProductSpecifications.Remove(productSpecification);
}
productToBeUpdated.ProductSpecifications = product.ProductSpecifications;
productToBeUpdated.ModifiedOn = DateTime.UtcNow;
await _unitOfWork.SaveChangesAsync();
return Ok(true);
}
I have also tried:
foreach (ProductSpecification productSpecification in productToBeUpdated.ProductSpecifications.ToList())
{
_unitOfWork.Repository<ProductSpecifications>().DeleteEntity(productSpecification);
}
Both of them throwing the following exception:
The instance of entity type 'ProductSpecification' cannot be tracked because another instance with the same key value for {'ProductId', 'ProductAttributeValueId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
Could not find where the problem actually lies! Any help will be highly appreciated!