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");
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");
}