Entity Framework : adding to one-to-many relationship gives concurrency exception

Viewed 115

I am trying to add to a one-to-many relationship. Once I try to save the newly created product using

context.saveChangesAsync() 
company.Products.Add(x) 

It won't allow me to - I get an exception:

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded.

I can't figure out where it's being modified. I hope you guys can help me out. Thanks in advance.

public async Task<Result<ProductDto>> Handle(Command request, CancellationToken cancellationToken)
{
    var company = await _context.Companies
                                .Include(x => x.Products)
                                .SingleOrDefaultAsync(a => a.UserId == _userAccessor.GetUserId());
        
    if (company != null)
    {
        var productToAdd = new Product
                               {
                                  Name = request.Product.Name,
                                  Description = request.Product.Description,
                                  SalePrice = request.Product.SalePrice,
                               };
                
        company.Products.Add(productToAdd);

        var result = await _context.SaveChangesAsync() > 0;
                
        if (!result)  
           return Result<ProductDto>.Failure("failed to create product");
    }
            
    return Result<ProductDto>.Success(request.Product);
}

public class Product : BaseEntity
{
    public Company Company { get; set; }
    public Guid CompanyId { get; set; }
    
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal SalePrice { get; set; }
    public decimal CostPrice { get; set; }
    public int VatPercentage { get; set; } = 25;
}

public class Company : BaseEntity
{
    public string CompanyName { get; set; }
    public string Address { get; set; }
    public string Zipcode { get; set; }
    public string City { get; set; }
    public string TaxId { get; set; }
    public string UserId { get; set; }

    public AppUser User { get; set; }

    public ICollection<Product> Products { get; set; } = new List<Product>();
}

I don't know why and can't seem to find the issue and what I'm doing wrong. My builder relationship are set:

modelBuilder.Entity("Domain.Entities.Company", b =>
    {
        b.Navigation("Products");
    });
 
 b.HasOne("Domain.Entities.Company", "Company")
                        .WithMany("Products")
                        .HasForeignKey("CompanyId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
 
 b.Navigation("Company"); 
1 Answers

try this, this way you don't need to use .Include(x => x.Products) to load the list of all products. It can save some network traffic and time. And add to list of products will work for a new company. When you donwload an existing company, ef tracks it and sometimes gives an excepton .

    
    if (company != null)
    {
        var productToAdd = new Product
                               {
                                 CompanyId=company.Id,

                                  Name = request.Product.Name,
                                  Description = request.Product.Description,
                                  SalePrice = request.Product.SalePrice,
                               };
                
        _context.Products.Add(productToAdd);

        var result = await _context.SaveChangesAsync();
                
        if (result == 0)  
           return Result<ProductDto>.Failure("failed to create product");
    }
Related