实体框架自引用键不写入数据库

本文关键字:数据库 框架 自引用 实体 | 更新日期: 2023-09-27 17:53:12

我有一个具有自引用键的实体框架代码第一个对象。当数据写入数据库时,子记录在自引用键中没有父id。

public class Contract
{
    public Contract()
    {
        Contracts = new List<Contract>();
    }

    public int Id { get; set; }
    public List<Contract> Contracts { get; set; }
}

对象具有比上面更多的属性,但为了示例起见,我已经简化了。这不是多对多的关系。每个合约只有一个父合约,除了没有父合约的主合约。

当我向合同列表中添加一个子合同并在DBContext上调用SaveChanges时,合同和子合同被写入数据库,所有字段都是正确的。除了实体框架生成的字段Contract_Id为空之外。

我有类似的自引用键与其他类正确工作,事实上合约有这些类作为属性。这些其他类都按预期工作,自引用键表示父对象都被正确填充。

我已经创建了一个非常简单的测试类,与上面相同,只是在类名前加上test,并且正常工作。我用我的Contract类创建了一个简单的测试,它不能正常工作。

我想能够做的是调试实体框架SaveChanges方法,但我不确定这是可能的。

有人知道我做错了什么或者如何调试这个吗?

实体框架自引用键不写入数据库

你必须这样修改你的实体:

public class Contract
{
  public Contract()
  {
    this.Contracts  = new List<Contract>();
  }
  public int Id { get; set; }
  public int? ContractParentId
  {
    get; set; 
  }
  public Contract ContractParent { get; set; }
  public List<Contract> Contracts { get; set; }
}

像这样使用:

using (var dbContext = new MyDatabaseContext(productionConnectionString))
{
  // You need this for fixup
  var contract1 = dbContext.Contracts.Create<Contract>();
  var contract2 = dbContext.Contracts.Create<Contract>();
  dbContext.Contracts.Add(contract1);
  dbContext.Contracts.Add(contract2);
  contract1.Contracts.Add(contract2);
  dbContext.SaveChanges();
}

你必须修改你的DbContext,因为不可能在代码中定义这种类型的关系,首先你需要Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  modelBuilder.Entity<Contract>().HasOptional(c => c.ContractParent).WithMany(c => c.Contracts).HasForeignKey(c => c.ContractParentId);
  base.OnModelCreating(modelBuilder);
}

试试这个:

你的模型:

public class Contract
{
    public Contract()
    {
        Contracts = new List<Contract>();
    }

    public int Id { get; set; }
    public virtual IList<Contract> Contracts { get; set; }
}

使用流畅的API,在你的DBContext上试试这个:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Contract>().HasMany(m => m.Contracts).WithMany();
}