You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL中正确配置表的SetNull选项?关联删除报错解决

解决EF Core中删除父表时子表外键无法设为Null的问题

问题场景

我通过EF Core定义了Category与Product实体,二者为一对多关联关系。尝试删除Category(父表)数据时,期望将关联Product(子表)的CategoryId字段设为Null,但触发报错:

Cannot create the foreign key "FK_Products_Categories_CategoryId" with the SET NULL referential action, because one or more referencing columns are not nullable.

相关代码

实体类定义

public class Category : BaseClass
{
    [MaxLength(50)]
    [Required]
    public string CategoryName { get; set; }
    [NotMapped]
    public IFormFile? Picture { get; set; }
    public List<Product> Products { get; set; }
}

public class Product : BaseClass
{
    [Required]
    [MaxLength(50)]
    public string Name { get; set; }
    [NotMapped]
    public string? Description { get; set; }
    [MaxLength(50)]
    [Required]
    public string Price { get; set; }
    [MaxLength(50)]
    public string? OldPrice { get; set; }
    [Required]
    public int Quantity { get; set; }
    [NotMapped]
    public IFormFile? Picture { get; set; }
    [MaxLength(50)]
    public string? DescriptionFileName { get; set; }
    public int? CategoryId { get; set; }
    public Category Category { get; set; }
}

public abstract class BaseClass
{
    [Key]
    public int Id { get; set; }
    public string PictureName { get; set; }
}

DbContext定义

public class AppDb : DbContext
{
    public AppDb(DbContextOptions<AppDb> options) : base(options)
    {

    }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Product> Products { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Category>()
            .HasMany(c=> c.Products)
            .WithOne(p => p.Category)
            .HasForeignKey(p => p.CategoryId)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.SetNull);
    }
}

问题原因

虽然Product类中的CategoryId声明为可空类型int?,但EF Core会根据导航属性Category的可空性推断外键列的约束:由于public Category Category { get; set; }是不可空引用类型,EF Core默认认为该外键是必填的,导致SET NULL操作无法生效。

解决方案

1. 修改导航属性为可空

将Product实体中的导航属性Category改为可空引用类型:

public Category? Category { get; set; }

2. (可选)明确配置外键可空性

在OnModelCreating中补充外键的可空配置,确保EF Core正确识别:

modelBuilder.Entity<Product>()
    .Property(p => p.CategoryId)
    .IsRequired(false);

3. 同步数据库Schema

生成新的迁移并更新数据库:

Add-Migration FixCategoryForeignKeyNullable
Update-Database

完成以上操作后,再次删除Category数据时,关联的Product的CategoryId会被正确设为Null。

内容的提问来源于stack exchange,提问作者Earlingh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 03:25:02