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

时间:2016-06-29 12:11:44

标签: c# entity-framework entity-framework-6

我有一个实体框架代码第一个带有自引用键的对象。当数据写入数据库时​​,子记录在自引用键中没有父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,它是null。

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

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

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

根据我做错了什么或如何调试,有谁知道要找什么?

2 个答案:

答案 0 :(得分:1)

您必须像这样修改您的实体:

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,因为在Code中首先你需要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);
}

答案 1 :(得分:0)

试试这个:

你的模特:

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();
}