为什么我不能将项目添加到数据库?

Why I can't add item to the database?

我正在开发我的网络应用程序。我正在使用 .NET 和 EntityFrameworkCore。我已经创建了迁移和数据库。简单地说,我只想将项目添加到数据库,但在向该特定端点发送请求时遇到错误。我在下面附上我的一些代码。我还将 link 附加到我的 github 回购 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;
    }

这里是 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; }
}

我还添加了一些实体配置

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

我终于在 Postman 和

中收到“SQLite 错误 19:'FOREIGN KEY constraint failed'”错误

Microsoft.EntityFrameworkCore.Database.Command[20102] 执行 DbCommand 失败(6 毫秒)[Parameters=[@p0='?' (大小 = 14),@p1='?' (大小 = 6),@p2='?' (Size = 5), @p3='?', @p4='?', @p5='?', @p6='?'], CommandType='Text', CommandTimeout='30'] 插入“产品”(“描述”、“名称”、“PictureUrl”、“价格”、“ProductBrandId”、“ProductTypeId”、“UserId”) 值(@p0、@p1、@p2、@p3、@p4、@p5、@p6); SELECT“身份” 从“产品” WHERE changes() = 1 AND "rowid" = last_insert_rowid(); ~ VScode

您应该使用现有(或新添加的)值填充 Product 对象中的 ProductBrandId、ProductTypeId 和 UserId 字段,以避免违反外键约束。

我发现您的示例和架构存在一些问题。首先,如前所述,您的产品具有您需要设置的 ProductType 和 ProductBrand 参考。通常,在您的 UI 中,您会有类似 drop-down 的列表,其中填充了 select 来自的类型和品牌,因此您的产品 DTO 需要 ProductTypeId 和 ProductBrandId 来表示这些 select离子。

实体可以公开 FK(根据 HasForeignKey 属性,您的实体确实显示有 FK,因此您可以在创建产品时设置这些。否则通常最好设置导航 属性 引用,因为这验证提供的 ID 实际上是有效的产品类型和品牌:

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

我通常不建议在您具有导航属性时公开 FK 属性,因为这会形成关系的 2 个真实来源。这通常只是更新时的问题,而不是创建时的问题。

最后你有一个用户参考,我认为这可能有点问题,具体取决于这种关系的实际用途。一个常见的情况是类似于跟踪 CreatedBy 类型的关系,尽管这将是一个 many-to-one 场景,其中用户不会费心维护与他们创建的产品(和其他实体)的关系。您的用户定义了一个 Products 集合,所以我会仔细看看这种关系应该是什么。在用户下的关系中,产品会与单个用户相关联,这似乎很奇怪。在我希望将用户与此类产品相关联的地方,我通常希望看到一个 many-to-many 关系,其中用户拥有与其相关联的产品,但这些产品可能与许多用户相关联。 (而不是专门分配给一个用户的不同产品)

目前你的产品有一个必需的用户参考,所以如果这需要与当前用户相关联,那么我会从你的身份验证状态或会话状态中获取当前用户 ID,并在创建时将其分配给产品以及。再次设置 FK 或加载用户实体并设置用户导航 属性