Home > OS >  Why I can't add item to the database?
Why I can't add item to the database?

Time:04-21

im working on my web app. Im using .NET and EntityFrameworkCore. I have created migration and database. Simply I just want to add item to the database but I encounter an error when sending a request to this particular endpoint. I attach some of my code below. I also attach link to my github repo https://github.com/szymi-dev/TestRepo

[HttpPost("add-product")]
    public async Task<ActionResult<Product>> AddProduct(ProductDto productDto)
    {
        var product = new Product
        {
            Name = productDto.Name,
            Price = productDto.Price,
            Descripiton = productDto.Descripiton,
            PictureUrl = productDto.PictureUrl
        };

        _context.Products.Add(product);
        await _context.SaveChangesAsync();

        return product;
    }

Here is productDTO class

public class ProductDto
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Descripiton { get; set; }
    public string PictureUrl { get; set; }
}

I have also added some Entity Configurations

public class ProductConfiguration : IEntityTypeConfiguration<Product>
{
    public void Configure(EntityTypeBuilder<Product> builder)
    {
        builder.Property(p => p.Id).IsRequired();
        builder.Property(p => p.Name).IsRequired().HasMaxLength(50);
        builder.Property(p => p.PictureUrl).IsRequired();
        builder.Property(p => p.Descripiton).HasMaxLength(180).IsRequired();
        builder.Property(p => p.Price).HasColumnType("decimal(18, 2)");
        builder.HasOne(p => p.ProductBrand).WithMany().HasForeignKey(k => k.ProductBrandId);
        builder.HasOne(p => p.ProductType).WithMany().HasForeignKey(k => k.ProductTypeId);
        builder.HasOne(p => p.User).WithMany(p => p.Products).HasForeignKey(k => k.UserId);
    }
}

Finally im getting " SQLite Error 19: 'FOREIGN KEY constraint failed'" error in Postman and

Microsoft.EntityFrameworkCore.Database.Command[20102] Failed executing DbCommand (6ms) [Parameters=[@p0='?' (Size = 14), @p1='?' (Size = 6), @p2='?' (Size = 5), @p3='?', @p4='?', @p5='?', @p6='?'], CommandType='Text', CommandTimeout='30'] INSERT INTO "Products" ("Descripiton", "Name", "PictureUrl", "Price", "ProductBrandId", "ProductTypeId", "UserId") VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6); SELECT "Id" FROM "Products" WHERE changes() = 1 AND "rowid" = last_insert_rowid(); ~ in VScode

CodePudding user response:

You should fill ProductBrandId, ProductTypeId and UserId fields in Product object with existing (or freshly added) values to avoid Foreign key constraint violations.

CodePudding user response:

There are a couple of issues I see with your example and your schema. Firstly, as mentioned your Product has a ProductType and ProductBrand reference that you will need to set. Typically in your UI you would have something like a drop-down list populated with Types and Brands to select from, so your Product DTO would need a ProductTypeId and ProductBrandId to represent these selections.

Entities can have a FK exposed (Which your entities do appear to have based on the HasForeignKey property, so you can set these when creating your product. Otherwise it is generally better to set navigation property references as this validates that the provided IDs are actually a valid product type and brand:

var productType = _context.ProductTypes.Single(x => x.ProductTypeId == productDto.ProductTypeId);
var productBrand = _context.ProductBrands.Single(x => x.ProductBrandId == productDto.ProductBrandId);


var product = new Product
{
    Name = productDto.Name,
    Price = productDto.Price,
    Descripiton = productDto.Descripiton,
    PictureUrl = productDto.PictureUrl,
    ProductType = productType,
    ProductBrand = productBrand
};

I don't generally recommend having FK properties exposed when you have navigation properties as this forms 2 sources of truth for the relationship. This is generally only an issue when updating, not creating though.

Lastly you have a User reference, which I think may be a bit of a problem depending on what this relationship is actually intended for. A common case for this would be something like tracking a CreatedBy type relationship, though this would be a many-to-one scenario where the user would not bother maintaining a relationship back to the products (and other entities) that they created. Your User has a Products collection defined, so I would take a close look at what this relationship should be. It seems odd that a product would be associated to a single user in a relationship under a user. Where I wanted to associate users to products like this I would typically expect to see a many-to-many relationship where a User has products associated to them, but those products could be associated to many users. (Rather than distinct products assigned exclusively to one user)

As it stands your product has a required User reference, so if this needs to be associated to the current user then I would fetch the current user ID from your Authentication state or session state and assign that to the Product on creation as well. Again either setting the FK or loading a User entity and setting the User navigation property

  • Related