实体框架核心:如何添加复合对象?

时间:2016-03-17 09:52:31

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

有以下复合对象,例如:

public class Parent
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("ChildRefId")]
    public Guid ChildId { get; set; }

    public Child Child { get; set; }
}

public class Child
{
    [Key]
    public Guid Id { get; set; }

    [ForeignKey("ParentRefId")]
    public int ParentId { get; set; }

    public Parent Parent { get; set; }
}

ParentChild具有一对一的关系:

modelBuilder.Entity<Parent>()
    .HasOne(parent => parent.Child)
    .WithOne(child => child.Parent)
    .WillCascadeOnDelete();

我尝试使用Parent创建新的Child并将其保存在数据库中:

var parent = new Parent { Child = new Child() };
dbContext.Parents.Add(parent);
dbContext.SaveChanges(); //<-- Exception!

...并获得以下异常:

System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Parent_Child_ChildId". The conflict occurred in database "MyDatabase", table "dbo.Child", column 'Id'.

如果我使用db上下文创建一个子项,它可以正常工作:

var child = dbContext.Childs.Add(new Child());
var parent = new Parent { Child = child };
dbContext.Parents.Add(parent);
dbContext.SaveChanges(); //<-- It works fine

问题#1:我可以轻松地将新实体添加到嵌套集合中,而无需使用上下文来创建它。但它不适用于一对一的关系。例如:

var parent = new Parent();
parent.Grandparents.Add(new Grandparent();
dbContext.Parents.Add(parent);
dbContext.SaveChanges(); //<-- It works fine and parent with one new grandparent were created!

为什么?

问题#2:请描述一下我做错了什么以及如何在没有上下文的情况下保存新父母以创建孩子(如嵌套馆藏)?

谢谢!

2 个答案:

答案 0 :(得分:2)

仅对beta-8版本的EF发生此错误。我更新EF后,rc1-final版本错误消失了。可能会解释beta-8版本尚未进行图表跟踪。

您可以找到更详细的信息here

答案 1 :(得分:1)

你应该删除流畅的语法声明(modelBuilder.Entity ...),在这个实例中不需要它。

您还需要使用上下文来创建对象,并且应该指定Id键值。通常使用Int作为键 - 与自动数据库插入注释相结合,为您生成键。 e.g。

public class Child {
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

[ForeignKey("ParentRefId")]
public int ParentId { get; set; }

public Parent Parent { get; set; }
}

您还应该使用上下文来创建类似于:

的模型对象
using(MyDbContext db = new MyDbContext()) {
  Child child = db.Childs.Create();
  Parent parent = db.Parents.Create();
  child.Parent = parent;
}
db.SaveChanges();
}