向Card表外键传入NULL触发Files表非空约束异常求助
问题描述
向Card表的外键字段传入NULL值时,触发PostgresException: 23502异常,提示“向files关系的name列添加NOT NULL条目时出现NULL值”。仅操作Card表却涉及Files表,需排查原因。
相关代码与结构
SQL表结构
CREATE TABLE Files ( id SERIAL PRIMARY KEY, name VARCHAR(30) NOT NULL, file bytea NOT NULL ); CREATE TABLE Card ( id SERIAL PRIMARY KEY, numMK INT NOT NULL, id_file INT, FOREIGN KEY (id_file) REFERENCES Files (id) );
C#实体类
public partial class Card { public int Id { get; set; } public int Nummk { get; set; } public int? IdFile { get; set; } public virtual FilePdf IdFileNavigation { get; set; } } public partial class FilePdf { public int Id { get; set; } public string Name { get; set; } public byte[] File1 { get; set; } public virtual ICollection<Card> Cards { get; } = new List<Card>(); }
EF Core配置代码
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Card>(entity => { entity.HasKey(e => e.Id).HasName("card_pkey"); entity.ToTable("card"); entity.Property(e => e.Id).HasColumnName("id"); entity.Property(e => e.Nummk).HasColumnName("nummk"); entity.HasOne(d => d.IdFileNavigation).WithMany(p => p.Cards) .HasForeignKey(d => d.IdFile) .HasConstraintName("card_id_file_fkey"); }); modelBuilder.Entity<FilePdf>(entity => { entity.HasKey(e => e.Id).HasName("filepdf_pkey"); entity.ToTable("files"); entity.Property(e => e.Id).HasColumnName("id"); entity.Property(e => e.File1) .IsRequired() .HasColumnName("file"); entity.Property(e => e.Name) .IsRequired() .HasMaxLength(30) .HasColumnName("name"); }); OnModelCreatingPartial(modelBuilder); }
添加Card数据的代码
using (var db = new TrappinganimalsContext()) { var card = new Card() { Id = 1, Nummk = 2312, IdFile = null, }; db.Cards.Add(card); db.SaveChanges(); }
问题原因
EF Core会自动跟踪实体的关联对象状态。虽然你设置了IdFile = null,但如果IdFileNavigation属性被意外初始化(比如默认构造、EF Core延迟加载创建的代理对象、自动映射工具赋值),EF Core会把这个空的FilePdf实例当成待插入的新实体。而Files表的name和file字段是NOT NULL约束,空FilePdf对象的这两个属性值为NULL,触发了23502异常。
解决方案
显式清空关联导航属性:创建Card对象时,同时设置
IdFileNavigation = null,避免EF Core跟踪空关联实体:var card = new Card() { Id = 1, Nummk = 2312, IdFile = null, IdFileNavigation = null };明确外键可为空的配置:在EF Core的Card实体配置中,显式声明外键非必填:
entity.HasOne(d => d.IdFileNavigation) .WithMany(p => p.Cards) .HasForeignKey(d => d.IdFile) .HasConstraintName("card_id_file_fkey") .IsRequired(false);排查意外赋值环节:检查是否有DTO转换、自动映射工具(如AutoMapper)在创建Card对象时,自动初始化了
IdFileNavigation属性,这类工具可能会默认创建关联对象实例。禁用不必要的延迟加载:如果不需要延迟加载功能,在DbContext配置中关闭,避免EF Core自动创建代理对象:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseNpgsql("你的连接字符串") .UseLazyLoadingProxies(false); }
内容的提问来源于stack exchange,提问作者Fa4stik
相关产品推荐
相关产品推荐

