插入外键对象插入新对象

Inserting of foreign key object inserts new object

当我使用 Entity Framework Core 将一个新的 MaskField 模型插入到我的数据库中时,它还会插入一个 Restriction 模型,该模型在 MaskField 模型中被引用。我试图让它只引用一个 Restriction 对象,因为当我试图在 MaskField.

中引用它时我已经知道该对象存在

我定义了一个 MaskField 模型:

[Table("MaskField", Schema = "dbo")]
public class MaskField
{
    [Key]
    public int maskId { get; set; }
        public Restriction? restriction { get; set; }
}

那个 MaskField 模型引用了其中的单个 Restriction 模型。这是 Restriction 模型:

[Table("Restriction", Schema = "dbo")]
public class Restriction
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int restrictionId { get; set; }
    [Required]
    public string? restrictionName { get; set; }
    [Required]
    public string? regex { get; set; }
}

我的DbContext:

public class MaskContext : DbContext
{
    public MaskContext(DbContextOptions options) : base(options) { }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MaskField>((mf) =>
        {
            mf.HasKey(e => new { e.maskId });
            mf.HasOne(e => e.restriction).WithMany();
        });
    }

    public DbSet<MaskField> MaskFields { get; set; }
    public DbSet<Restriction> Restrictions { get; set; }
}

尝试插入包含限制的 MaskField 最终执行:

INSERT INTO [dbo].[Restriction] ([restrictionId], [regex], [restrictionName])
VALUES (@p0, @p1, @p2); 

最终出错,因为 IDENTITY_INSERT 被禁用。关于如何 只是 引用它而不是尝试插入新的 Restriction 模型有什么想法吗?

编辑:这是插入 MaskField

的代码
public class MaskRepository : IMaskRepository
{
    MaskContext dbContext;
    public MaskRepository(MaskContext dbContext)
    {
        this.dbContext = dbContext;
    }

    public async Task<MaskField> CreateAsync(Mask _object)
    {
        var obj = await dbContext.MaskFields.AddAsync(_object);
        dbContext.SaveChanges();
        return obj.Entity;
    }
}

我找到了一个不太好的解决方法。

因此,仅引用 Restriction 非常简单,只需更改行 public Restriction? restriction {get;set;} 引用 Restriction 的密钥,例如:public int? restrictionId {get;set;}

然而,由于我想在一个查询中提取整个 Restriction 对象,所以我被迫拥有两个字段,如下所示:

[Table("MaskField", Schema = "dbo")]
public class MaskField
{
    [Key]
    public int maskId { get; set; }
    
    public int? restrictionId { get; set; }
    public Restriction? restrictionId { get; set; }
}

这似乎是一个很好的解决方案,直到我意识到将该对象保存/更新到数据库时会导致相同的原始问题。

为了解决这个问题,我在保存和更新函数中添加了逻辑,以便在保存之前将这些字段设置为空:

public class MaskRepository : IMaskRepository
{
    MaskContext dbContext;
    public MaskRepository(MaskContext dbContext)
    {
        this.dbContext = dbContext;
    }

    public async Task<MaskField> CreateAsync(MaskField _object)
    {
        _object.restriction = null;

        var obj = await dbContext.MaskFields.AddAsync(_object);
        dbContext.SaveChanges();
        return obj.Entity;
    }
}

终于找到了解决这个问题的正确方法。 您可以将 [JsonIgnore] 字段添加到模型 类 以阻止模型甚至首先被提交到 ef 核心。

在这种情况下它将是:

[Table("MaskField", Schema = "dbo")]
public class MaskField
{
    [Key]
    public int maskId { get; set; }
    
    public int? restrictionId { get; set; }
    [JsonIgnore]
    public Restriction? restriction { get; set; }
}