`违反外键约束`当父亲和孩子都是新的

问题描述

我正在尝试创建一个新实体,其中包含一组新实体。程序抛出一个 dbupdateException 表示我试图违反外键约束:

PostgresException:23503:插入或更新表“reagent_used_on_assay”违反外键约束“fk_reagent_used_on_assay”

这是简化的调用堆栈:

await this.DbContext.Database.BeginTransactionAsync()

AssayEntity assay = _dbContext.Assays.CreateProxy();

_dbContext.Assays.Add(assay);

ReagentUsedOnAssay reagentUsedOnAssay = _dbContext.ReagentsUsedOnAssay.CreateProxy();

_dbContext.ReagentsUsedOnAssay.Add(reagentUsedOnAssay);

entity.UsedBy = assay;
entity.BasedOnFk = 42; // existing Reagent id

assay.Reagents.Add(reagentUsedOnAssay)

await this.DbContext.SaveChangesAsync(); // throws dbupdateException

await this.DbContext.Database.CurrentTransaction.CommitAsync();

我不明白为什么会出现外键约束违规错误,因为我确实在子级上设置了导航属性并将子级添加到父导航集合属性中(显然无法在子级上设置外键属性)因为尚未分配)。

我注意到如果我调用它会起作用

_dbContext.ReagentsUsedOnAssay.Add(reagentUsedOnAssay);

在子节点上设置导航属性后。但是这样做,在调用 DbSet.Add 方法之前,我无法访问此实体上的任何导航属性,在我的情况下,这可能会导致其他问题。

以下是一些附加信息:

sql 表:

CREATE TABLE public.assay
(
    id integer NOT NULL DEFAULT nextval('assay_id_seq'::regclass),CONSTRAINT pk_assay_id PRIMARY KEY (id)
)

CREATE TABLE public.reagent
(
    id integer NOT NULL DEFAULT nextval('reagent_id_seq'::regclass)
)

CREATE TABLE public.reagent_used_on_assay
(
    based_on integer NOT NULL,used_by integer NOT NULL,expires_at timestamp(0) with time zone,CONSTRAINT pk_reagent_used_on_assay PRIMARY KEY (based_on,used_by),CONSTRAINT fk_reagent_used_on_assay FOREIGN KEY (used_by)
        REFERENCES public.assay (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,CONSTRAINT fk_reagent_used_on_assay_reagent FOREIGN KEY (based_on)
        REFERENCES public.reagent (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)

POCO 课程:

public class AssayEntity
{
    public AssayEntity()
    {
        this.Reagents = new HashSet<ReagentUsedOnAssayEntity>();
    }

    public int Id { get; set; }

    public virtual ICollection<ReagentUsedOnAssayEntity> Reagents { get; set; }
}

public class ReagentEntity
{
    public ReagentEntity()
    {
        this.ReagentsUsedOnAssay = new HashSet<ReagentUsedOnAssayEntity>();
    }

    public int Id { get; set; }
    public int AppliquedInFk { get; set; }
    public string Name { get; set; }
    public string Reference { get; set; }
    public string Manufacturer { get; set; }
    public bool NoExpiration { get; set; }
    public string Gtin { get; set; }

    public virtual AssayTemplateEntity AppliquedIn { get; set; }
    public virtual ICollection<ReagentUsedOnAssayEntity> ReagentsUsedOnAssay { get; set; }
}

public class ReagentUsedOnAssayEntity
{
    public int BasedOnFk { get; set; }
    public int UsedByFk { get; set; }
    public DateTime? ExpiresAt { get; set; }

    public virtual ReagentEntity BasedOn { get; set; }
    public virtual AssayEntity UsedBy { get; set; }
}

实体框架映射:

modelBuilder.Entity<AssayEntity>(entity =>
{
    entity.ToTable("assay");

    entity.Property(e => e.Id).HasColumnName("id");
});

modelBuilder.Entity<ReagentEntity>(entity =>
{
    entity.ToTable("reagent");

    entity.Property(e => e.Id).HasColumnName("id");
});

modelBuilder.Entity<ReagentUsedOnAssayEntity>(entity =>
{
    entity.HasKey(e => new { e.BasedOnFk,e.UsedByFk })
        .HasName("pk_reagent_used_on_assay");

    entity.ToTable("reagent_used_on_assay");

    entity.Property(e => e.BasedOnFk).HasColumnName("based_on");

    entity.Property(e => e.UsedByFk).HasColumnName("used_by");

    entity.Property(e => e.ExpiresAt)
        .HasColumnName("expires_at")
        .HasColumnType("timestamp(5) with time zone");

    entity.HasOne(d => d.BasedOn)
        .WithMany(p => p.ReagentsUsedOnAssay)
        .HasForeignKey(d => d.BasedOnFk)
        .OnDelete(DeleteBehavior.ClientSetNull)
        .HasConstraintName("fk_reagent_used_on_assay_reagent");

    entity.HasOne(d => d.UsedBy)
        .WithMany(p => p.Reagents)
        .HasForeignKey(d => d.UsedByFk)
        .OnDelete(DeleteBehavior.ClientSetNull)
        .HasConstraintName("fk_reagent_used_on_assay");
});

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)